背景
使用 Docker 自部署 Supabase,实现短信登录+自定义短信提供商
Supabase
supabase 是一个开源的后端即服务(BaaS)平台。核心特点:
- 企业级 PostgreSQL 数据库,自动生成 RESTful API 和 GraphQL API
- 基于 JWT 的用户管理系统,行级安全策略(RLS)保护数据
- 边缘函数,基于 deno 的无服务器函数,可运行自定义后端逻辑
- 实时功能、文件存储(本次不涉及)
值得注意的是 supabase 自部署版本相比官网阉割了一些功能,例如
- 平台是多项目,但自部署只能单项目
- 平台可以在线编辑边缘函数,自部署不行
- supabase 的 cli 不能给自部署的实例使用
方法
Docker 安装
清华大学镜像站 docker-ce | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
安装后 Post-installation steps | Docker Docs
Docker 配置 JSON File logging driver | Docker Docs
Supabase 自部署
官方文档 Self-Hosting with Docker | Supabase Docs
自定义短信发送
自定义短信发送 Send SMS Hook | Supabase Docs
短信登录 api Phone Login | Supabase Docs
自定义短信发送的边缘函数实际上是一个 webhook,在 auth 服务配置好该 webhook,会被 auth 调用,在 webhook 中需要实现对短信自定义发送所需密钥的检验和根据 webhook 的 payload 取出验证码并使用自己的服务进行发送
提示
文档前面都给了,但是实操过程中还是会有很多问题,下面是一些提示
- 自部署中,环境变量都是通过 compose 文件和 .env 文件注入的,也就是说,如果你要新增一个变量,需要同时在 .env 中新增和在 compose 文件对应的 service 的 environment 中新增该变量
- 边缘函数的 Deno 环境变量也是如此,例如,实现 webhook 需要自定义密钥
- 短信调用的 edge function 需要用到 host.docker.internal 地址,该地址在 Docker Desktop 下是自动配置好的,但是在 docker-ce 上需要自行在 compose 文件中进行指定
- 一些短信的高级配置在 supabase 的文档中没有(例如过期时间等),需要查看 supabase auth 开源库的文档,进行配置
- edge function 偶现报错的问题
是因为 edge function 的入口是通过 functions/main 实现的,该功能引用了 deno.land 的包,而国内网络连接不稳定导致
解决方法,使用 npm 包而不是 deno.land 包、配置 .npmrc 使用国内镜像,避免网络问题导致冷启动不稳定 - supabase studio 上无法查看日志
Supabase Studio not showing logs because endpointlogs.allis not delivering logs · Issue #37218 · supabase/supabase
这个官方已经修复了,只是 master 分支上的 docker 文件里 studio 的镜像版本还没有更新,可以自己更新一下 studio 的 image 版本 - supabase studio 上无法查看 edge function & cron 日志
修复中Edge function & Cron logs not visible in Studio on fresh self-hosted install · Issue #38121 · supabase/supabase - webhook 密钥的 token 部分的长度最小是 64,这个是标准 webhook 规范要求的,小于 64 会报错
- 更新 webhook 文件后可以单独重启 webhook 服务,不必重启所有
docker compose restart functions --no-deps
附录
注册自定义短信发送Hook
# .env
ENABLE_PHONE_SIGNUP=true
ENABLE_PHONE_AUTOCONFIRM=false
GOTRUE_HOOK_SEND_SMS_ENABLED=true
GOTRUE_HOOK_SEND_SMS_URI=http://host.docker.internal:8000/functions/v1/send_sms
GOTRUE_HOOK_SEND_SMS_SECRETS=v1,whsec_<your token 64>
GOTRUE_SMS_OTP_EXP=900
GOTRUE_SMS_OTP_LENGTH=6
GOTRUE_SMS_PROVIDER=twilio
GOTRUE_MAILER_EXTERNAL_HOSTS=<host part of your site url >