通过 Tailscale 在 Railway 上私有部署 Drizzle Studio 或 Gateway

在 Railway 上部署 Drizzle Studio 或 Drizzle Gateway,使其仅能通过你的 tailnet 访问。

如果你已经在 Railway 上运行 Drizzle Studio 或 Drizzle Gateway,请改为按照通过 Tailscale 为 Railway 上的 Drizzle Studio、Gateway 或数据库添加私有访问进行操作。

本指南假设你已经:
  • 拥有 Railway 账户。

  • 拥有 Tailscale 账户。

  • 已在工作机器上安装 Tailscale 客户端,并登录到你的 tailnet。可从 Tailscale 网站下载客户端。

  • tailnet 已启用 MagicDNS,因为地址和机器名称都依赖它。2022-10-20 及之后创建的 tailnet 默认启用 MagicDNS。若你的 tailnet 创建时间更早,请检查 DNS 页面。

工作原理

该模板会创建两项服务。一项运行数据库 UI,即 Drizzle Studio 或 Drizzle Gateway;另一项是 Tailscale 服务,它会作为独立机器加入你的 tailnet,并通过 Railway 私有网络将端口转发到数据库 UI。流量从你的设备经 tailnet 到达该机器,再由它连接数据库 UI。

数据库 UI 通过 Railway 私有网络连接数据库。数据库继续使用 *.railway.internal 域名,并且无法从其他位置访问。

浏览器通过 tailnet 连接 Tailscale 服务;该服务在 Railway 私有网络中连接 Drizzle Studio 或 Gateway,再由其连接 Postgres。 浏览器通过 tailnet 连接 Tailscale 服务;该服务在 Railway 私有网络中连接 Drizzle Studio 或 Gateway,再由其连接 Postgres。

设置 Railway 项目

创建一个包含 PostgreSQL 数据库且未启用公共访问的项目。如果项目中已有数据库,请跳到选择 Gateway 或 Studio。

创建 Railway 项目

登录 Railway 控制面板,然后点击 New Project 按钮。

Railway 创建菜单中已选中 Database

创建 PostgreSQL 数据库

在项目画布中,点击右上角的 New 按钮,然后选择 Database → PostgreSQL。你也可以使用命令面板( ⌘K CtrlK )并搜索 PostgreSQL。

Railway 数据库菜单中已选中 PostgreSQL

将数据库保留在私有网络中

点击 PostgreSQL 服务,打开 Settings 选项卡并找到 Networking 区域。确认公共访问已关闭。在 Private Networking 下方可以看到服务的私有域名,例如 postgres.railway.internal。

Postgres Settings 选项卡中显示公共访问已关闭及私有域名 postgres.railway.internal

选择 Gateway 或 Studio

Drizzle 提供两种数据库 UI,并分别提供对应的 Tailscale 模板。

Drizzle StudioDrizzle Gateway
数据库一个,使用你在 Railway 中设置的 DATABASE_URL多个,可在 UI 中添加和编辑
访问方式模板生成的 PASSCODEMASTERPASS,以及你分配给其他用户的访问码
存储无用于保存连接的卷

如果 tailnet 中的所有人都只需要访问同一个数据库,请选择 Drizzle Studio。

如果你需要管理多个数据库,或向特定人员开放指定数据库,请选择 Drizzle Gateway。知道 MASTERPASS 的 Gateway 用户可以添加该服务能够访问的任何数据库连接。

Drizzle Studio
Drizzle Gateway

打开模板

点击下方按钮打开 Drizzle Studio with Tailscale 模板。

**请先不要部署。**先设置变量。

部署到 Railway

打开 Deploy to 下拉菜单并选择数据库所在的项目。

Drizzle Studio with Tailscale 部署表单中,DATABASE_URL 已设为 Postgres 引用

设置变量

变量设置内容
DATABASE_URL必填。此字段为空。从列表中选择数据库服务,然后选择 DATABASE_URL。如果服务名为 Postgres,字段值会显示为 ${{Postgres.DATABASE_URL}}。
PASSCODE保留生成的值,或输入自己的访问码。
TS_FORWARD_DATABASE可选。如果你还想从 tailnet 访问数据库(例如使用 drizzle-kit),请从列表中选择数据库服务的 RAILWAY_PRIVATE_DOMAIN。机器上的 5432 端口随后会通过 Railway 私有网络转发到数据库。你也可以稍后在 Tailscale 服务的 Variables 选项卡中设置。
TS_HOSTNAME保留 drizzle-studio,也可以为机器选择其他名称。

某些变量(例如 TS_HOSTNAME)位于卡片中折叠的 Pre-Configured Environment Variables 区域。展开后即可查看或修改。

部署模板

在每张服务卡片上点击 Save Config,然后点击 Review and deploy。Railway 会在侧边栏中打开包含该模板的项目。在侧边栏中点击 Deploy Template。

项目画布中位于 Postgres 旁边的 Tailscale 和 Drizzle Studio 服务

通过部署日志登录

打开 Tailscale 服务,进入其 Deployments 选项卡并查看部署日志。日志末尾会显示登录链接:

This service is not on your tailnet yet. Open this link and sign in
with the account that owns your tailnet:
  https://login.tailscale.com/a/xxxxxxxxxxxx

打开链接并登录。最先打开链接的人会将这台机器加入其 tailnet,因此不要转发链接。只有 Railway 项目成员可以查看该日志。

Tailscale 部署日志中的登录提示和隐藏链接

如果你的 tailnet 要求审批设备,日志会显示相关提示;在机器页面批准设备后,机器才会继续运行。

从部署日志读取地址

登录几秒后,同一日志中会显示访问地址:

joined tailnet: example.com
4983: ready
open https://drizzle-studio.example-com.ts.net from any device on your tailnet

Tailscale 部署日志中的已加入 tailnet、open 和 4983 ready 行

确认 tailnet 名称属于你。如果不是,说明其他人先打开了登录链接,他们的 tailnet 现在可以访问此服务。要重新取得服务控制权:

  1. 在项目画布上点击 Tailscale 服务下方的卷,打开其 Settings 选项卡并点击 Wipe volume。
  2. 输入确认文本并点击 Wipe。Railway 会删除机器密钥并重新部署服务。
  3. 自行打开新部署日志中的登录链接。
  4. 更改 Drizzle Studio 服务中的 PASSCODE。如果设置了 TS_FORWARD_DATABASE,也请更改数据库用户的密码。

如果 tailnet 中已有同名机器,新机器名称会以 -1、-2 等后缀结尾。请使用日志中显示的地址。

如果 tailnet 未启用 HTTPS 证书,地址会以 http:// 开头并以 :4983 结尾。无论使用哪种地址,Tailscale 都会加密连接。若要使用 https:// 地址,请在 DNS 页面启用 HTTPS Certificates。

如果设置了 TS_FORWARD_DATABASE,日志中还会显示 5432: ready。

打开 Drizzle Studio

在浏览器中打开该地址。首次通过 https:// 访问时,Tailscale 服务仍在获取证书,因此页面可能失败或需要约两分钟才能加载。如果遇到此情况,请重新加载页面。

首次使用时,Drizzle Studio 会要求输入访问码。

Drizzle Studio 访问码提示,并提醒在 Railway 容器变量中查看 PASSCODE

在 Railway 中打开 Drizzle Studio 服务,进入 Variables 选项卡并复制 PASSCODE 的值,然后粘贴到输入框中。

Drizzle Studio Variables 选项卡中标出的 PASSCODE

检查连接

Drizzle Studio 会打开 DATABASE_URL 指向的数据库。

通过 tailnet 访问的 Drizzle Studio,其中打开了 posts 表

使用其他端口

默认情况下,TS_FORWARD_BROWSER 在机器和服务两端都使用 4983 端口,TS_FORWARD_DATABASE 使用 5432 端口。若要使用其他端口,请按 [port:]host[:port] 格式填写:

值机器上的端口服务上的端口
host默认端口默认端口
host:portportport
source_port:host:target_portsource_porttarget_port

例如,5433:${{Postgres.RAILWAY_PRIVATE_DOMAIN}}:5432 会将机器上的 5433 端口转发到数据库服务的 5432 端口。

如果 TS_FORWARD_BROWSER 在机器上使用的端口不是 4983,日志中的 http:// 地址就会以该端口结尾。

禁用密钥过期

通过登录加入 tailnet 的机器会按照 tailnet 的计划过期密钥,默认期限为 180 天。密钥过期后,Tailscale 服务会显示新的登录链接并等待操作。在你点击链接前,访问地址将不可用。

若要避免这种情况,请打开机器页面,找到该机器,打开所在行最右侧的菜单并选择 Disable key expiry。

Tailscale 机器页面菜单中的 Disable key expiry 选项

如果你使用自动化部署且不希望登录操作,需在 Tailscale 服务中设置 TS_AUTHKEY:

  • 如果使用 auth key,将 TS_AUTHKEY 设为该密钥。
  • 如果使用 OAuth client secret,将 TS_AUTHKEY 设为该密钥,并在末尾添加 ?ephemeral=false&preauthorized=true。如果没有此后缀,Tailscale 会在机器断开连接时移除它,并要求在重新加入前审批。还需将 TS_TAGS 设为你拥有的标签,例如 tag:drizzle。带标签的机器密钥不会过期。

Tailscale 服务只会在机器加入前读取 TS_AUTHKEY。如果机器已经加入,请先移除机器并清空卷。

排查 Tailscale 设置问题

展开与你遇到的情况相符的条目。

日志中出现了新的登录链接

服务已重启,例如密钥过期或机器被移除后。请打开最新的链接。该链接只能使用一次。

日志显示机器正在等待审批

你的 tailnet 已启用设备审批。请打开机器页面并批准该设备。

Studio 已打开,但没有显示数据表

新数据库在应用 Schema 前不会有数据表。请按照通过 Tailscale 使用 Drizzle Kit 连接 Railway 私有数据库创建数据表。如果数据库中已有数据表,请检查 Drizzle Studio 服务的 Variables 选项卡中的 DATABASE_URL。它可能指向项目外的服务,或包含与数据库不匹配的连接字符串。请将其设为 ${{Postgres.DATABASE_URL}},并将 Postgres 替换为你的数据库服务名称,然后点击 Deploy。

访问地址无法打开

请按顺序检查以下原因:

  • 你的设备登录了其他 tailnet。在设备上运行 tailscale status,并确认 tailnet 与日志中显示的一致。
  • 日志显示的是 http:// 地址。请使用包含端口的完整地址,因为只有 tailnet 启用了 HTTPS 证书时才能使用 https://。
  • 首次通过 https:// 访问时,Tailscale 服务仍在获取证书。请等待约两分钟后重新加载页面。
  • MagicDNS 未启用,因此地址无法解析。请在 DNS 页面启用 MagicDNS。

此前一直正常,几个月后突然停止工作

机器密钥已过期。打开 Tailscale 服务的部署日志并使用新显示的登录链接,然后为该机器禁用密钥过期,以免再次发生。

机器名称末尾多了 -1 后缀

你的 tailnet 中已存在同名机器,例如之前部署时创建的机器。Tailscale 会保留该后缀。如果想使用较短名称,请在机器页面中重命名;否则请使用日志中显示的地址。

日志中没有 open 行

TS_FORWARD_BROWSER 为空,或被 Tailscale 服务跳过。如果引用指向的服务在模板部署时不属于该项目,它就会解析为空值。被跳过的变量会在日志中单独显示一行,后续条目会说明该行的含义。打开 Tailscale 服务的 Variables 选项卡,将 TS_FORWARD_BROWSER 设为 ${{"Drizzle Gateway".RAILWAY_PRIVATE_DOMAIN}}(Studio 服务则使用 "Drizzle Studio"),然后点击顶部栏的 Deploy。

日志中的某行以 skipped 结尾

该行以变量名称开头,后面会给出原因:

  • does not match [port:]host[:port]:值中包含多于两个冒号。
  • has an empty target host:值中有端口但没有主机名。引用项目外服务时会解析为空主机名。
  • still contains a Railway reference that did not resolve:Railway 未替换该引用。请检查引用中的服务名称。
  • has a port outside 1-65535:端口值不在 1 到 65535 范围内。
  • reuses port:此前的转发规则已在机器上使用该端口。
  • uses port 443, which the https listener owns:请为机器选择其他端口。启用 HTTPS 证书后,数据库 UI 地址已经使用 443 端口。

在 Tailscale 服务的 Variables 选项卡中修正该值,然后点击顶部栏的 Deploy。

后续步骤