通过 Tailscale 为 Railway 上的 Drizzle Studio、Gateway 或数据库添加私有访问

Railway 私有网络只能由项目内部的服务访问。若要从自己的机器访问 Drizzle Studio 或 Drizzle Gateway,服务就需要公共域名,而公共域名对互联网上的所有人开放。

本指南会在已运行 Drizzle Studio 或 Drizzle Gateway 的项目中添加 Tailscale 服务。数据库 UI 随后会获得一个仅 tailnet 设备可访问的地址,你也可以移除其公共域名。数据库本身也可以获得相同的私有地址,这样即使关闭公共网络访问,你机器上的 drizzle-kit 或桌面数据库客户端仍可连接数据库。

如果你尚未部署 Drizzle Studio 或 Gateway,请按照通过 Tailscale 在 Railway 上私有部署 Drizzle Studio 或 Gateway进行操作。

本指南假设你已经:
  • 在项目中运行名为 Drizzle Studio 或 Drizzle Gateway 的服务。

  • 拥有 Tailscale 账户。

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

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

添加 Tailscale 服务

选择对应数据库 UI 的选项卡。

Drizzle Studio
Drizzle Gateway

打开模板

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

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

部署到 Railway

打开 Deploy to 下拉菜单并选择 Drizzle Studio 服务所在的项目。

Tailscale for Drizzle 部署表单中,TS_FORWARD_BROWSER 已设置为引用 Drizzle Studio 服务

设置变量

变量设置内容
TS_FORWARD_BROWSER此字段为空。从列表中选择 Studio 服务的 RAILWAY_PRIVATE_DOMAIN。字段值会显示为 ${{"Drizzle Studio".RAILWAY_PRIVATE_DOMAIN}}。
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。

移除公共域名

此步骤为可选操作。若不执行,数据库 UI 仍可通过公共域名和 tailnet 访问。

打开 Drizzle Studio 服务的 Settings 选项卡并找到 Networking 区域。如果 Railway 自动生成了公共域名,请将其移除并保留私有域名。

Drizzle Studio Settings 选项卡中标出的公共域名删除按钮

通过部署日志登录

打开 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 结尾。

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

打开 Drizzle Studio

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

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

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

在 Railway 中打开 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 设置问题

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

日志中没有 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。

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

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

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

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

访问地址无法打开

请按顺序检查以下原因:

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

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

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

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

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

后续步骤