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

<p/><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/3895637-c2369f086893d8e8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>
</p><p><strong>前言</strong></p><p>关注技术前沿的我们,想必对<strong>BaaS</strong> 都不陌生。从 <strong>Firebase</strong> 横空出世,再到<strong>2014</strong>年的一声炮响。它已经给全世界开发者,带来了大量便捷的,开箱即用的开发运维环境,加上它优秀的开发体验。这让我们程序员们能够以很少的人力成本,做出功能丰富的应用。</p><p>然而出于众所周知的原因,它在我们国内是无法使用的。</p><p>于是利用这信息不对称的效果:国内一批独立的公司还有一些大厂,对 <strong>Firebase</strong> 这个产品进行"借鉴" 从而做出了自己的 <strong>XXbase</strong>。比如某里云的XXX,某讯云的XXX,还有xxCloud的XXX,等等</p><p>然而笔者在比较深度使用国内这些后,发现开发体验不佳。而且很多功能,由于服务的不完善,功能开发不出来,需要额外的服务器去部署功能容器作为辅助。这显然背离了使用 <strong>BaaS</strong> 的初衷。于是我们这批开发者将眼光投向了开源 <strong>BaaS</strong>解决方案.</p><p><strong>开源 </strong></p><p>笔者主要研究的开源 <strong>BaaS</strong> 解决方案主要有<strong>2</strong>个,一个是 <strong>supabase</strong> ,另外一个是 <strong>appwrite</strong>,当然除此之外还有 <strong>amplication</strong> 和国人的项目 <strong>laf</strong>(向优秀的开源人致敬!)</p><p>为什么选择<strong>supabase</strong> 和 <strong>appwrite</strong> 呢?因为它们功能成熟,社区稳定,私有化部署便捷,更重要的是它们背后有资本的扶持,比较商业化,不会因为一些莫名其妙的变故,突然跑路,导致项目太监。</p><p>另外在线的<strong>supabase</strong>服务,虽然在中国可用,但是部署地域只能选择韩国,日本,新加坡,印度等亚洲地区。部署后浅尝辄止地用一下看似可行。一旦深入使用,遇到那些需要对内置功能进行扩展,或者要在里面嵌入自己的后端服务的场景时,一个一个坑就会接踵而至。所以为了避免这些因为网络原因导致的<strong>issue</strong>,我们选择私有化部署。</p><p>本篇文章就来教你如何一步一步,把 <strong>supabase</strong> 部署到自己的服务器上。</p><p><strong>快速开始</strong></p><blockquote><p>本篇文章以 Linux (ubuntu 22) 服务器为基础平台,假如你是本机测试部署,记得先安装 docker 和 git</p></blockquote><p><strong>获取部署文件</strong></p><p><strong>supabase</strong> 官方为我们提供了 <strong>docker compose</strong> 私有化部署的配置目录,就在 <strong>github/supabase</strong> <strong>master</strong>分支的 <strong>docker</strong> 目录下。</p><p>让我们获取它!</p><pre># Get the code
git clone --depth 1  

 Go to the docker folder

cd supabase/docker

 Copy the fake env vars

cp .env.example .env

 Start 直接使用默认配置

docker compose up -d</pre><blockquote><p>假如因为网络原因,拉镜像太慢或者失败,记得提前配置好 <strong>dockerhub</strong> 的国内源,比如 <strong>网易源</strong>,<strong>百度源</strong>,<strong>腾讯源</strong>,<strong>阿里源</strong> 等等,具体配置方法网上一搜就有。</p></blockquote><p>然后 <strong>docker</strong> 就跑去拉镜像去了,利用这段时间我们可以先看看 <strong>docker-compose.yml</strong> 里面到底配置了哪些服务。</p><p><strong>服务明细</strong></p><p>从配置中,我们可以看到它有这些服务,以及对应的那些镜像:</p><pre>// docker-compose.ymlconst 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'
    }</pre><p>不过日志服务依赖 <strong>Google Cloud</strong> 的 <strong>BigQuery</strong> 功能,看到 <strong>Google</strong> 这个关键字,你就明白在国内你是用不了的,</p><p>所以不要开启内置日志服务,应该自己处理后接入 阿里云/腾讯云 日志系统。</p><p><strong>容器启动后</strong></p><p>看到这,现在你的所有镜像应该已经下载完成,并且启动好了吧。</p><p>现在直接使用的是 <strong>.env.example</strong> 里带的默认配置,访问 <strong>http://localhost:3000</strong> 进入 <strong>Supabase Studio</strong></p><p>检测一下各项功能是否运转良好,<strong>log</strong>功能应该是<strong>500</strong>的,因为没有开启。</p><p><strong>创建一个前端app</strong></p><p>接下来我们创建一个前端app, 这里我们快速创建一个 <strong>vite</strong> 应用。</p><p>然后安装 <strong>@supabase/supabase-js</strong> 并初始化:</p><pre>import { createClient } from '@supabase/supabase-js'
// 你的服务器+端口:  
// 自建服务时候,记得要新建入方向规则安全策略组哦,不然服务器默认只能被访问到 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)</pre><p>接着快速写一个使用邮箱登录页面,然后就能实现登录/注册功能了:</p><pre>const email = ''
const { error } = await supabase.auth.signInWithOtp({
  email})</pre><p>然后点击按钮,你就会发现,报错了,为什么注册不了呢?原因在于我们没有配置真实的邮箱配置。</p><p><strong>注册邮箱SMTP协议</strong></p><p>首先我们找到 <strong>.env</strong> 的 <strong>Email auth</strong> 配置,发现需要配置许多的 <strong>SMTP_*</strong>配置</p><p>这里以大家都有的 <strong>QQ邮箱</strong> 为例,来把你的 <strong>QQ邮箱</strong> 作为你这个 <strong>supabase实例</strong>发送邮件的邮箱。</p><p>首先登录你的 <strong>QQ邮箱</strong>,然后右上角你的头像,点击设置:</p><p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/3895637-aa705eabe630dfb9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>
</p><p>然后获取授权码,保存好:</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/3895637-47da5ea475102b90.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>
</p><p>接下来就可以这样配置环境变量:</p><pre>## 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 # 发信人</pre><p>配置好之后,<strong>docker compose up -d</strong> 重启服务</p><p>邮件登录和注册就好了,默认长这样,当然你也可以自定义邮件模板:</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/3895637-2bc5969b1acbe2ed.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>Image</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/3895637-db951f1937090618.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p>Image</p><p>
</p><p>是不是特别简单,当然一般正式环境,我们会更换正式的企业邮箱。</p><p><strong>jwt token和kong网关配置并应用</strong></p><p>我们需要生成和配置自己的秘钥,所以我们利用加密算法生成符合要求的 <strong>JWT_SECRET</strong> 后,我们可以在 <a>api-keys#Generate JWT</a> 生成相应的 <strong>ANON_KEY</strong> 和 <strong>SERVICE_ROLE_KEY</strong>.</p><p>然后同时去修改:</p><ul><li><p><strong>.env</strong></p></li><ul><li><p><strong>ANON_KEY</strong></p></li><li><p><strong>SERVICE_ROLE_KEY</strong></p></li></ul><li><p><strong>volumes/api/kong.yml</strong></p></li><ul><li><p><strong>anon</strong></p></li><li><p><strong>service_role</strong></p></li></ul></ul><p>秘钥一定要匹配,不然会报错,然后重启容器应用即可。</p><p><strong>更改数据库密码</strong></p><p>我们之前一直使用的默认的密码,现在我们要换成自己的密码,然后更换之后,你会开心的发现服务挂了。</p><p>这是为什么呢?原因在于数据库已经用你之前的密码初始化完成了,这时候其他服务用了新的密码去连接原先的数据库自然就会挂掉,然后被不断的重启。</p><p>那怎么办?实际上也很简单:</p><p>还记得 <strong>volumes</strong> 挂载目录下有很多的脚本吗?其中有一个 <strong>volumes/db/roles.sql</strong>,里面就是把新的环境变量设置成密码的脚本</p><p><strong>docker exec -it <container_name/id> sh</strong> 然后 <strong>su postgres</strong> ,<strong>psql</strong> 执行一下搞定。</p><p>当然你也可以使用真男人喜欢用的方式:</p><pre>rm -rf docker/volumes/db/data</pre><p><strong>k8s 部署参考</strong></p><p>目前官方维护的主要是 <strong>docker compose</strong> 的部署方式,那我们要用 <strong>k8s</strong> 部署,应该怎么办呢?</p><p>社区给我们 <strong>2</strong> 种解决方案:</p><ol><li><p><a>supabase-kubernetes</a></p></li><li><p><a>kompose</a></p></li></ol><p>详情可以点击链接阅读文档</p><p><strong>尾言</strong></p><p>通过这种方式,你就可以快速在服务器上部署自己的 <strong>supabase</strong> 应用,看似很美,不过你访问 <strong>studio</strong> 的时候会发现,相比在线版本少了很多的功能。毕竟人家是商业项目,给我们用用大部分功能已经很不错了,所以接下来我们就需要自己写一套后端,来接入这套机制,从而自己去开发一些定制化的功能。</p><p>不过文章写到这也太长了,一般到这能完整的部署一套的也比较少了,就让我挖个坑下期再见吧。</p><p><strong>常见问题</strong></p><p><strong><strong>name resolution failed</strong></strong></p><p>这是由于你 <strong>kong</strong> 网关里转发的某些服务没有正常启动,报的错误,你可以 <strong>docker ps -f name=supa</strong> 看看哪些服务是异常的,并使用 <strong>docker logs</strong> 查看异常容器里的日志进行处理。</p><pre>password authentication failed for user &quot;authenticator&quot;\n","hint":null,"message":"Database connection error. Retrying the connection."}</pre><pre>{"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&nbsp;user=supabase_auth_admin&nbsp;database=postgres: failed SASL auth (FATAL: password authentication failed for user &quot;supabase_auth_admin&quot; (SQLSTATE 28P01))"}</pre><p><strong><strong>Invalid authentication credentials</strong></strong></p><p>由于更改了数据库的用户密码,导致 <strong>auth</strong> 和 <strong>rest</strong> 这些服务因为数据库授权原因,挂了,一直在重启</p><p>这是由于你没有同时在 <strong>.env</strong> 和 <strong>volumes/api/kong.yml</strong> 里配置同样的 <strong>anon</strong> 和 <strong>service</strong> <strong>Key</strong>,配置好了之后重启一下容器/重启一下 <strong>kong</strong></p><p><strong>参考链接</strong></p><p><a>https://supabase.com/docs/guides/self-hosting</a></p><p><a>https://github.com/supabase-community/supabase-kubernetes</a></p><p><a>https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes/</a></p><p><a>https://supabase.com/docs/refer</a></p><p>
</p>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容