使用 Supabase 进行自托管
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
请注意,本文仍在撰写中。如有任何建议或疑问,请在评论区留言。
相关材料:
Supabase是什么?
Supabase 是一款基于 Postgres 的开源数据库解决方案。它不仅包含 Postgres 的所有标准功能,还新增了一些强大的功能,例如实时流和 REST API。所有这些功能都由极其强大的库提供支持。
自托管的优缺点
您可能出于多种原因想要自行托管 Supabase:
-
更多数据库空间——通过使用您自己的VPS,您可以拥有比Supabase托管平台(目前)提供的数据库大得多的数据库。
-
完全掌控基础设施——一切尽在您的掌控之中,因此如果您需要进行更改,您可以随时进行更改。
您可能出于以下几个原因而选择让 Supabase 托管您的数据库而不是自行托管:
-
它已经设置好了——您无需具备深厚的技术知识即可在其平台上设置 Supabase 实例。
-
费用——他们提供免费套餐,可能足以满足您的需求。
这篇文章是写给谁看的?
本文旨在帮助那些想要自行托管 Supabase 但可能被市面上各种自行托管指南搞得晕头转向的用户。请注意,目前自行托管的方案不包含控制面板。如果您非常在意这一点,那么本指南可能不适合您。
为了更好地理解本文,强烈建议您具备以下方面的基本经验:
- Nginx - 配置端点/代理
- Docker - 部署和配置 Dockerfile
即使你缺乏这些技能,我也尽力解释了关键部分以及你需要更改的文件。
我们将使用 Portainer 来管理 Docker 容器。我们还将使用 Cloudflare 的服务。为此,我们将使用db.example.com作为我们的域名。稍后将在 Nginx 配置部分详细介绍。
准备工作
首先,你需要搭建一个服务器托管空间。我个人推荐 DigitalOcean,因为几乎所有操作都可以通过其网页控制面板完成。本文中提到的“Droplet”指的是一个虚拟专用服务器(VPS),它将托管我们的 Supabase 实例。
Supabase 为多个平台提供了一键部署功能,但我们不会使用这些功能,因为它们不包含完整的 Supabase 体验。
我们将改用 Docker。许多 VPS 提供商已经提供了“即用型”Docker 实例。我建议使用现成的实例,因为与手动设置 Docker 相比,这可以节省大量时间。
假设您已设置好运行 Docker 的 Droplet/VPS,那么首先要做的就是安装 Portainer。为此,请按照https://documentation.portainer.io/v2.0/deploy/ceinstalldocker/上的指南进行操作。截至撰写本文时,安装 Portainer 仅需 3 个步骤:
- SSH 连接到您的 VPS
- 跑步
docker volume create portainer_data - 跑步
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
接下来,您需要对 Portainer 进行一些基本配置。请在您的网络浏览器中访问 [此处插入http://<ip-of-your-vps>:9000网址] 并按照屏幕上的说明进行操作。
接下来,我们需要配置 Nginx。幸运的是,使用 Portainer 可以轻松完成这项工作。
继续操作前的可选提示:设置 2 个卷,nginx-config和nginx-data,然后volumes在设置 Nginx 时使用选项卡中的这些卷。
从 Portainer 控制面板的左侧菜单中,选择“应用程序模板”,然后从列表中选择“Nginx”,然后按照说明操作。
通过 Portainer 部署
如果你之前阅读过本指南,我建议你创建一个 supabase 代码库的分支。但现在我不再推荐这样做,因为有更好、更简化的方法。
返回 Portainer 网络控制面板,从左侧菜单中选择“堆栈”,然后单击“添加堆栈”。
给你的堆栈命名,然后选择“Git 存储库”。对于存储库 URL,请输入 supabase 存储库的完整 URL(https://github.com/supabase/supabase)。
在“编写路径”字段中,输入/docker/docker-compose.yml。
将 .env 文件( https://github.com/supabase/supabase/blob/master/docker/.env.example )的内容复制到一个空白文件中,并使用有效信息更新以下值:
OPERATOR_TOKEN=your-super-secret-operator-token
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
# some SMTP server to send your auth-mails with
SMTP_HOST=mail.example.com
SMTP_PORT=
SMTP_USER=
SMTP_PASS=
在“环境变量”下,点击“高级模式”,然后复制并粘贴文件内容.env。
最后,点击底部的“部署堆栈”。此过程可能需要几分钟才能完成。完成后,从 Portainer 菜单中点击“容器”。您可能会注意到 supabase-auth 最初并未运行。只需选中它,然后点击“启动”。之后它应该就能正常运行了。
本节的最后一步是为每个 Supabase 服务配置主机名。在 Portainers 控制面板的“容器”菜单项中,选择每个 Supabase 容器。点击页面顶部的“复制/编辑”。然后,滚动到页面底部,选择“高级容器设置”下的“网络”选项卡。在“主机名”字段中,输入服务的名称。例如,对于容器supabase-rest,将主机名设置为 `<service_name> rest`。您可以将其设置为任何名称,但我建议使其与容器相关。最后,点击“部署此容器”。系统会警告您已存在同名容器 - 点击“确定”。稍等片刻,容器将使用新主机名重新部署。对每个 Supabase 容器重复这些步骤。
这样做有助于 Nginx 连接到容器,并使其更容易在基础设施的其他部分中被识别。
关于 supabase-auth 容器,有一点非常重要:默认情况下,它DATABASE_URL会包含 ` sslmode=disable<sup>`。此值中的等号可能会导致错误。例如,如果您尝试.signUp()从 supabase-js 库调用 `<method>` 方法,则可能会收到 500 错误。原因是它会尝试连接到 `<sup>`disable而不是 `<sup>`。postgres://<db_user>:<password>@db:<db_port>/postgres?sslmode=disable
解决方法是确保sslmode=disable从 URL 中删除所有查询参数。
配置 Nginx
为了配置 Nginx 以支持 Supabase 所需的各种服务,我们需要修改 Nginx 配置。
为此,您需要通过 SSH 连接到服务器,然后cd找到存储 Nginx 配置的卷。如果您nginx-config按照上述步骤设置了卷,则该卷(通常)位于/var/lib/docker/volumes/nginx-config/_data。
接下来,我们需要修改两个文件。第一个是nginx.conf……
在该http部分内,添加以下内容:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server realtime:4000;
}
我们需要修改的另一个文件是conf.d/default.conf。配置 Nginx 的方法有很多种,但为了简单起见,我们将只在一个文件中进行配置。
在 中conf.d/default.conf,将所有内容替换为以下内容:
server {
listen 443 ssl;
server_name db.example.com;
# REST
location ~ ^/rest/v1/(.*)$ {
proxy_set_header Host $host;
proxy_pass http://kong:8000;
proxy_redirect off;
}
# AUTH
location ~ ^/auth/v1/(.*)$ {
proxy_set_header Host $host;
proxy_pass http://kong:8000;
proxy_redirect off;
}
# REALTIME
location ~ ^/realtime/v1/(.*)$ {
proxy_redirect off;
proxy_pass http://kong:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
让我解释一下这里发生了什么。
首先,我们的 REST 处理程序会监听发送到/rest/v1该路径的所有请求,以及该路径之后添加的所有内容。然后,它会将这些请求路由到 Supabase Kong 服务器,该服务器默认情况下可通过内部访问http://kong:8000。
同样,我们的身份验证处理程序正在监听对 的请求/auth/v1,并将它们路由到 Kong。
最后,实时订阅由路由处理/realtime/v1。同样,这条路由指向 Kong。
如果你读过本指南的最初版本,我当时建议你将请求路由到各个单独的服务。但经过进一步研究,我们发现路由到 Kong 才是更好的解决方案。
我们执行此代理的原因是,它可以确保来自 Supabase 库(例如@supabase/supabase-js)的请求能够正确地路由到堆栈中的不同服务。
Kong 将根据 URL 处理每个请求到其相应服务的路由,而 Nginx 提供了一种在单个 URL 下公开这些端点的方法。
修改完成后,保存文件,然后从 Portainer 控制面板重启 Nginx 容器。为确保一切运行正常,请选择 Nginx 容器,然后点击“查看日志”。日志应显示一切运行正常。
最后,从 Nginx 容器(在 Portainer 控制面板中),将其连接到supabase_default网络——该选项位于控制面板页面的底部。
必要的 Kong 配置
在 Portainer 中,从“卷”菜单选项创建一个新卷。给新卷命名kong-data。
然后,返回“容器”,选择“supabase-kong”容器。点击顶部的“复制/编辑”。
滚动到页面底部,点击“卷”。点击“映射其他卷”。在标有“容器”的字段中输入/var/lib/kong。然后点击其右侧的“卷”按钮。
从下面的下拉菜单中选择您刚才创建的“kong-data”卷。然后单击“部署此容器”。
GoTrue / 身份验证环境变量
默认情况下,每个容器的环境变量应该都能正常工作,但 GoTrue / auth 容器可能需要一些额外的配置。
为了简单起见,这里提供一个可在 supabase-auth 容器中使用的环境配置示例 - 您可以根据需要进行编辑:
GOTRUE_OPERATOR_TOKEN=your-super-secret-operator-token
GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated
# Make sure this JWT secret matches what was configured during setup
GOTRUE_JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
# How long should JWT tokens be valid for?
GOTRUE_JWT_EXP=3600
# Since Supabase is based on Postgres, you shouldn't need to change this
GOTRUE_DB_DRIVER=postgres
# What schema should requests be routed to?
# There should be no reason to change this
DB_NAMESPACE=auth
# Where is our auth/GoTrue located
# You shouldn't need to change these unless the ports are mapped differently
GOTRUE_API_HOST=0.0.0.0
PORT=9999
# Email settings
# You must set these if you want to be able to send emails
GOTRUE_SMTP_HOST=smtp.your-email-host.com
GOTRUE_SMTP_PORT=465
GOTRUE_SMTP_USER=your-smtp-user
GOTRUE_SMTP_PASS=your-smtp-password
# Should users be required to confirm their email address before they can log in?
# If set to false, users won't have to confirm their registration
# If set to true, users will have to click the link in their email to confirm
GOTRUE_MAILER_AUTOCONFIRM=false
# What is the 'from' address that emails are sent from?
GOTRUE_SMTP_ADMIN_EMAIL=noreply@example.com
# Remove this if you don't want debug logs
GOTRUE_LOG_LEVEL=debug
# The connection string for your database
# `@db` says we're looking for the container called 'db' on our docker network
DATABASE_URL=postgres://postgres:your-super-secret-and-long-postgres-password@db:5432/postgres
# Email templates
# Invite user - provide a URL to a HTML or Text template
GOTRUE_MAILER_TEMPLATES_INVITE=https://example.com/path/to/your/invite/template.html
# Confirm registration - provide a URL to a HTML or Text template
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=https://example.com/path/to/your/confirmation/template.html
# Password recovery - provide a URL to a HTML or Text template
GOTRUE_MAILER_TEMPLATES_RECOVERY=https://example.com/path/to/your/password_reset/template.HTML
# Magic link - provide a URL to a HTML or Text template
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=https://example.com/path/to/your/magic_link/template.html
# GoTrue URLs
# These are appended after the API_EXTERNAL_URL
# You shouldn't need to change these
GOTRUE_MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_INVITE=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_RECOVERY=/auth/v1/verify
# Site URLs
# This is where the user will be redirected to after clicking a link in an email and after oAuth
GOTRUE_SITE_URL=https://example.com/redirect_to_here
GOTRUE_URI_ALLOW_LIST=https://example.com/redirect_to_here
# This is the URL where your supabase stack is accessible
# i.e. this is the endpoint URL you would pass into a `createClient()` call in the supabase-js library
API_EXTERNAL_URL=https://database.example.com/
# Set this to true if you want to prevent signing up with email and password
GOTRUE_DISABLE_SIGNUP=true
# oAuth
# If you are not using oAuth to login (e.g. Login with Facebook), you can ignore the below
# If you want to disable oAuth for a specific provider, set the `GOTRUE_EXTERNAL_<provider>_ENABLED` to false
# Github oAuth
GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=your_github_client_id
GOTRUE_EXTERNAL_GITHUB_SECRET=your_github_client_secret
GOTRUE_EXTERNAL_GITHUB_ENABLED=true
# Google oAuth
GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOTRUE_EXTERNAL_GOOGLE_SECRET=your-google-secret
GOTRUE_EXTERNAL_GOOGLE_ENABLED=true
# Facebook oAuth
GOTRUE_EXTERNAL_FACEBOOK_CLIENT_ID=your-facebook-client-id
GOTRUE_EXTERNAL_FACEBOOK_SECRET=your-facebook-app-secret
GOTRUE_EXTERNAL_FACEBOOK_ENABLED=true
# Add other oAuth provider details below
最终检查
到目前为止,一切应该都运行正常。
您应该能够使用 VPS IP 地址、端口 5432 以及postgres您在环境变量中设置的用户名和 postgres 密码连接到您的 Postgres 服务器。
结语
如前所述,本文仍在完善中。我仍在研究如何配置 Supabase 堆栈以实现自托管的一些细节。文章中可能缺少一些内容——请留言告知,我会考虑添加。
自托管 Supabase 的配置绝非易事,而且仍有改进空间。希望本文能帮助您加快配置过程,助您顺利开启 Supabase 之旅。
文章来源:https://dev.to/chronsyn/self-hosting-with-supabase-1aii