此页面需要javascript支持,请在浏览器中启用javascript

符合国情的supabase私有化部署(0)

supabase
私有化
BaaS
docker
compose
共2566个字,阅读时间 13 分钟
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://icebreaker.top/articles/2023/5/30-supabase-self-hosting-0

Image

符合国情的 supabase 私有化部署 (0)

前言

关注技术前沿的我们,想必对BaaS 都不陌生。从 Firebase 横空出世,再到2014年的一声炮响。它已经给全世界开发者,带来了大量便捷的,开箱即用的开发运维环境,加上它优秀的开发体验。这让我们程序员们能够以很少的人力成本,做出功能丰富的应用。

然而出于众所周知的原因,它在我们国内是无法使用的。

于是利用这信息不对称的效果:国内一批独立的公司还有一些大厂,对 Firebase 这个产品进行 "借鉴" 从而做出了自己的 XXbase。比如某里云的 XXX,某讯云的 XXX,还有 xxCloud 的 XXX,等等

然而笔者在比较深度使用国内这些后,发现开发体验不佳。而且很多功能,由于服务的不完善,功能开发不出来,需要额外的服务器去部署功能容器作为辅助。这显然背离了使用 BaaS 的初衷。于是我们这批开发者将眼光投向了开源 BaaS解决方案.

开源 BaaS 解决方案

笔者主要研究的开源 BaaS 解决方案主要有2个,一个是 supabase ,另外一个是 appwrite,当然除此之外还有 amplication 和国人的项目 laf(向优秀的开源人致敬!)

为什么选择supabaseappwrite 呢?因为它们功能成熟,社区稳定,私有化部署便捷,更重要的是它们背后有资本的扶持,比较商业化,不会因为一些莫名其妙的变故,突然跑路,导致项目太监。

另外在线的supabase服务,虽然在中国可用,但是部署地域只能选择韩国,日本,新加坡,印度等亚洲地区。部署后浅尝辄止地用一下看似可行。一旦深入使用,遇到那些需要对内置功能进行扩展,或者要在里面嵌入自己的后端服务的场景时,一个一个坑就会接踵而至。所以为了避免这些因为网络原因导致的issue,我们选择私有化部署。

本篇文章就来教你如何一步一步,把 supabase 部署到自己的服务器上。

快速开始

本篇文章以 Linux (ubuntu 22) 服务器为基础平台,假如你是本机测试部署,记得先安装 docker 和 git

获取部署文件

supabase 官方为我们提供了 docker compose 私有化部署的配置目录,就在 github/supabase master分支的 docker 目录下。

让我们获取它!

# Get the code
git clone --depth 1 https://github.com/supabase/supabase

# Go to the docker folder
cd supabase/docker

# Copy the fake env vars
cp .env.example .env

# Start 直接使用默认配置
docker compose up -d

假如因为网络原因,拉镜像太慢或者失败,记得提前配置好 dockerhub 的国内源,比如 网易源,百度源,腾讯源,阿里源 等等,具体配置方法网上一搜就有。

然后 docker 就跑去拉镜像去了,利用这段时间我们可以先看看 docker-compose.yml 里面到底配置了哪些服务。

服务明细

从配置中,我们可以看到它有这些服务,以及对应的那些镜像:

// docker-compose.yml
const serviceMap = {
    // supabase 后台管理系统
    studio: 'supabase/studio',
    // 大名鼎鼎的云原生网关
    kong: 'kong',
    // gotrue 原先是 netlify 的项目,主要用来做认证的,目前已经失去维护
    // 所以 supabase 自个fork了一份,自己维护了,主要用来管理和校验 jwt token
    // 除此之外台还有邮件,手机验证码的发送校验等等许多的功能
    auth: 'supabase/gotrue',
    // 为 postgres 生成 restful api 来进行常规的 crud 操作
    rest: 'postgrest/postgrest',
    // 基于 postgres 的 websocket 全双工通信服务
    realtime: 'supabase/realtime',
    // S3 文件存储服务,同时存储元数据进 postgres
    // 个人建议。私有化部署不要用这个服务,因为这不符合国情
    // 作为代替,可以使用阿里云/腾讯云的 oss/cos服务
    storage: 'supabase/storage-api',
    // 图片处理鉴权服务
    imgproxy: 'darthsim/imgproxy',
    // 为 postgres 生成一套 restful api 来对数据库进行管理,执行命令等等
    meta: 'supabase/postgres-meta',
    // serverless 函数计算服务,基于 Deno runtime,不是 nodejs 哦
    functions: 'supabase/edge-runtime',
    // postgres database,核心,强依赖,supabase很多功能依赖这个数据库,换其他的不行
    db: 'supabase/postgres'
}
// 另外如果你要开启日志,你还需要同时 apply docker-compose-logging.yml
// docker-compose-logging.yml
// 相比默认额外加了2个服务
const loggingServiceMap = {
    // 日志服务
    // logflare 被 supabase 收购了
    analytics: 'supabase/logflare',
    // 高性能的数据日志收集,转化,路由和事件触发服务
    // 可以把自己生成的日志转化成,其他云平台需要的格式
    vector: 'timberio/vector'
}

不过日志服务依赖 Google CloudBigQuery 功能,看到 Google 这个关键字,你就明白在国内你是用不了的,

所以不要开启内置日志服务,应该自己处理后接入 阿里云 / 腾讯云 日志系统。

容器启动后

看到这,现在你的所有镜像应该已经下载完成,并且启动好了吧。

现在直接使用的是 .env.example 里带的默认配置,访问 http://localhost:3000 进入 Supabase Studio

检测一下各项功能是否运转良好,log功能应该是500的,因为没有开启。

创建一个前端 app

接下来我们创建一个前端 app, 这里我们快速创建一个 vite 应用。

然后安装 @supabase/supabase-js 并初始化:

import { createClient } from '@supabase/supabase-js'
// 你的服务器+端口: http://xxx.xxx.xxx.xxx:8000
// 自建服务时候,记得要新建入方向规则安全策略组哦,不然服务器默认只能被访问到 80/443/22 等等端口
// 具体怎么建,你需要看看你的服务商操作文档
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

const supabase = createClient(supabaseUrl, supabaseAnonKey)

接着快速写一个使用邮箱登录页面,然后就能实现登录 / 注册功能了:

const email = ''
const { error } = await supabase.auth.signInWithOtp({
  email
})

然后点击按钮,你就会发现,报错了,为什么注册不了呢?原因在于我们没有配置真实的邮箱配置。

注册邮箱 SMTP 协议

首先我们找到 .envEmail auth 配置,发现需要配置许多的 SMTP_*配置

这里以大家都有的 QQ邮箱 为例,来把你的 QQ邮箱 作为你这个 supabase实例发送邮件的邮箱。

首先登录你的 QQ邮箱,然后右上角你的头像,点击设置:

Image

然后获取授权码,保存好:

Image

接下来就可以这样配置环境变量:

## Email auth
SMTP_ADMIN_EMAIL=icebreaker99@qq.com # 你的邮箱
SMTP_HOST=smtp.qq.com # 固定的
SMTP_PORT=465 # 固定的
SMTP_USER=icebreaker99@qq.com # 你的邮箱
SMTP_PASS=xxxxx # 这里就是你刚刚获取的授权码
SMTP_SENDER_NAME=icebreaker # 发信人

配置好之后,docker compose up -d 重启服务

邮件登录和注册就好了,默认长这样,当然你也可以自定义邮件模板: Image Image

是不是特别简单,当然一般正式环境,我们会更换正式的企业邮箱。

jwt token 和 kong 网关配置并应用

我们需要生成和配置自己的秘钥,所以我们利用加密算法生成符合要求的 JWT_SECRET 后,我们可以在 api-keys#Generate JWT 生成相应的 ANON_KEYSERVICE_ROLE_KEY.

然后同时去修改:

  • .env
    • ANON_KEY
    • SERVICE_ROLE_KEY
  • volumes/api/kong.yml
    • anon
    • service_role

秘钥一定要匹配,不然会报错,然后重启容器应用即可。

更改数据库密码

我们之前一直使用的默认的密码,现在我们要换成自己的密码,然后更换之后,你会开心的发现服务挂了。

这是为什么呢?原因在于数据库已经用你之前的密码初始化完成了,这时候其他服务用了新的密码去连接原先的数据库自然就会挂掉,然后被不断的重启。

那怎么办?实际上也很简单:

还记得 volumes 挂载目录下有很多的脚本吗?其中有一个 volumes/db/roles.sql,里面就是把新的环境变量设置成密码的脚本

docker exec -it <container_name/id> sh 然后 su postgres ,psql 执行一下搞定。

当然你也可以使用真男人喜欢用的方式:

rm -rf docker/volumes/db/data

k8s 部署参考

目前官方维护的主要是 docker compose 的部署方式,那我们要用 k8s 部署,应该怎么办呢?

社区给我们 2 种解决方案:

  1. supabase-kubernetes
  2. kompose

详情可以点击链接阅读文档

尾言

通过这种方式,你就可以快速在服务器上部署自己的 supabase 应用,看似很美,不过你访问 studio 的时候会发现,相比在线版本少了很多的功能。毕竟人家是商业项目,给我们用用大部分功能已经很不错了,所以接下来我们就需要自己写一套后端,来接入这套机制,从而自己去开发一些定制化的功能。

不过文章写到这也太长了,一般到这能完整的部署一套的也比较少了,就让我挖个坑下期再见吧。

常见问题

name resolution failed

这是由于你 kong 网关里转发的某些服务没有正常启动,报的错误,你可以 docker ps -f name=supa 看看哪些服务是异常的,并使用 docker logs 查看异常容器里的日志进行处理。

password authentication failed for user \"authenticator\"\n","hint":null,"message":"Database connection error. Retrying the connection."}
{"level":"info","msg":"Go runtime metrics collection started"}
{"args":[0.018145916],"component":"pop","level":"info","msg":"%.4f seconds"}
{"level":"fatal","msg":"running db migrations: Migrator: problem creating schema migrations: couldn't start a new transaction: could not create new transaction: failed to connect to `host=db user=supabase_auth_admin database=postgres`: failed SASL auth (FATAL: password authentication failed for user \"supabase_auth_admin\" (SQLSTATE 28P01))"}

Invalid authentication credentials

由于更改了数据库的用户密码,导致 authrest 这些服务因为数据库授权原因,挂了,一直在重启

这是由于你没有同时在 .envvolumes/api/kong.yml 里配置同样的 anonservice Key,配置好了之后重启一下容器 / 重启一下 kong

参考链接

https://supabase.com/docs/guides/self-hosting

https://github.com/supabase-community/supabase-kubernetes

https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes/

https://supabase.com/docs/reference/self-hosting-analytics/introduction