关于 railway
面向 Agent 的 Railway 运维技能,涵盖部署、日志、指标、变量和服务访问,并强调遵循仓库部署策略、最小化操作及授权范围。
主要功能
- 01项目与部署发现
- 02构建、运行时及 HTTP 日志诊断
- 03CPU、内存与延迟指标
- 04按授权范围管理变量和部署
- 05Railway run、shell 与 SSH 操作
适用场景
- 01调查 Railway 构建失败
- 02排查服务崩溃原因
- 03检查资源使用与请求延迟
- 04执行已获授权的重启或重新部署
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ onsager-ai/ dev-skills --skill railway安装后在 Claude Code 中输入/railway确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/debug.shpreflight.shsmoke.sh详细介绍
railway
为任务选择可用的最小 Railway 操作。选择部署路线前,请阅读仓库的 AGENTS.md 和部署策略。 由 GitHub 驱动的流水线优先于下方通用的 CLI 示例。 此技能提供工具操作方法,不代表有权绕过该流水线。
部署路线与授权
- 对于仓库代码更改,准备分支/PR,并使用已声明的 CI/CD 触发方式。对于由 GitHub 驱动的服务,观察相应的提交部署;不要上传工作区副本、修改源分支/固定版本,也不要手动应用平台补丁来触发重新部署。
- 手动重启、重新部署或更改源代码/配置,需要在用户授权范围内有运维理由,例如从已诊断出的失败发布中恢复。记录理由、确切的环境/服务以及预期效果。
- 复用针对此操作和范围的现有授权。仅在意图未明确、影响具有破坏性或涉及额外范围时请求决策。只读诊断、可逆的代码修复和 PR 准备无需再次确认。
- 测试证据应与运行时能力和授权分开报告。不要要求提供新的资格报告或检查清单,作为测试许可。
此技能的触发场景
应由以下短语触发:
- 部署 / 构建
- “将此部署到 railway”
- “推送到 railway”、“发布到 railway”、“railway up”
- “railway 上的构建失败了”、“我的构建为什么失败了”
- 日志 / 调试
- “显示 railway 日志”、“实时查看日志”、“railway logs --since 1h”
- “我的服务为什么在 railway 上崩溃”
- “显示 railway 上的 500 错误”、“显示 HTTP 日志”、“显示慢请求”
- “在 railway 日志中查找请求 ID abc123”
- 运维
- “在 railway 上重新部署”、“重启 API 服务”、“回滚上一次部署”
- “扩展我的 railway 服务”、“移除最新部署”
- 状态 / 发现
- “列出我的 railway 项目”、“此项目中有哪些服务”、“列出部署”
- “我的 railway 项目状态如何”、“我的服务是否健康”
- 变量
- “设置 railway 环境变量 FOO=bar”、“列出 railway 变量”、“删除 railway 变量”
- 运行 / 连接
- “使用 railway 生产环境变量运行此脚本”、“使用 railway 环境变量打开 shell”
- “通过 SSH 连接到我的 railway 服务”、“连接到我的 railway postgres / redis / mongo”
- 指标
- “railway 上的 CPU/内存是多少”、“我的服务是否触及限制”
- “railway 上的 p95 延迟”、“/api 的请求速率”
以下情况请跳过:
- 主机不是 Railway(Fly、Render、Vercel、AWS 等)。此技能了解
railwayCLI,不具备通用性。 - 修复只是代码更改,没有运维操作——让常规开发流程技能处理代码;等到需要部署或查看日志时再回到这里。
前置条件
- 检查可用工具目录。对于受支持的平台读取,使用已认证的 Railway 连接器;对于本地工作区、SSH 或精确命令工作流,使用 CLI。如果存在等效的已配置连接器,则无需全局安装 CLI,也无需显示令牌。
- 使用 CLI 时,检查
command -v railway和railway --version,然后通过有界的账户/项目读取来诊断身份验证。切勿打印令牌、令牌前缀或环境。复用 CLI 登录状态或注入的凭据。RAILWAY_API_TOKEN作用于账户范围;RAILWAY_TOKEN作用于项目/环境范围。工作区列表读取被拒绝,并不能证明项目范围的读取也会失败。 - 明确项目、环境和服务 ID。只读发现不得修改已关联的上下文。请求安装、登录或更广泛的访问权限前,先诊断命令实际返回的 401/403、不受支持的标志或缺失的工具。优先使用等效的已配置能力。仅在请求的操作需要且处于授权范围内时,才安装/更新工具。
操作流程
此技能是一个小型状态机。选择能够回答用户问题的最小入口;不要执行用户未要求的发现操作。
┌──────────┐
│ Discover │ list projects / services / deployments / env / vars
└────┬─────┘
▼
┌──────────┐ ┌──────────┐
│ Debug │◄──────►│ Metrics │ logs (build/deploy/http) + cpu/mem/p95
└────┬─────┘ └──────────┘
▼
┌──────────┐
│ Fix │ variables set / code edit / config change
└────┬─────┘
▼
┌──────────┐ ┌──────────┐
│ Deploy │───────►│ Verify │ up / redeploy / restart / down / roll back
└──────────┘ └──────────┘
第 1 步 — 发现
始终先捕获所需的 ID,以便后续调用明确。优先使用 JSON 输出以便解析。
# Workspace-wide view (requires an account token).
railway list --json
# A single project's structure (project token works here too if you pass --project).
railway status --json --project "$PROJECT_ID"
# Services and environments inside that project.
railway service list --json --project "$PROJECT_ID" --environment production
railway environment list --json --project "$PROJECT_ID"
# Deployments for a specific service (most recent first).
railway deployment list \
--project "$PROJECT_ID" \
--service api \
--environment production \
--limit 20 --json
从 JSON 中捕获:项目 ID、环境 ID/名称(通常为 production、staging,以及 PR 预览环境)、服务 ID/名称、最新部署 ID 及其 status(SUCCESS、FAILED、BUILDING、DEPLOYING、CRASHED、REMOVED)。部署状态能告诉你问题出在构建、启动还是稳定运行阶段——据此选择相应的日志流。
第 2 步 — 调试(先看日志)
Railway 提供三种日志流。选择与故障模式相匹配的日志流;混用会让日志尾部难以阅读。
| 流 | 标志 | 适用情况 |
|---|---|---|
| 部署 / 运行时 | railway logs(默认) | 应用已启动但行为异常,或启动后崩溃。 |
| 构建 | railway logs --build [DEPLOYMENT_ID] | 部署状态为 FAILED,且从未进入运行时。 |
| HTTP | railway logs --http | 问题涉及状态码、延迟激增或特定请求。 |
在 Agent 会话中,默认使用历史记录、非流式查询——流式输出会让 shell 挂起。使用 --lines、--since 或 --until 中的任意一个都会禁用流式输出。
# Last 200 deploy log lines, JSON for parsing.
railway logs \
--project "$PROJECT_ID" --service api --environment production \
--lines 200 --json
# Build logs for the failed deployment specifically.
railway logs --build "$DEPLOYMENT_ID" \
--project "$PROJECT_ID" --service api --environment production \
--lines 500
# Errors only in the last hour.
railway logs --since 1h --filter "@level:error" --lines 100 \
--project "$PROJECT_ID" --service api --environment production
# All 5xx HTTP responses in the last 30 minutes.
railway logs --http --since 30m --status ">=500" --lines 200 \
--project "$PROJECT_ID" --service api --environment production --json
# Slow GETs on a specific path.
railway logs --http --method GET --path /api/users \
--filter "@totalDuration:>=1000" --lines 50 --json \
--project "$PROJECT_ID" --service api --environment production
# Trace one request end-to-end.
railway logs --http --request-id "$REQUEST_ID" --lines 50 --json \
--project "$PROJECT_ID" --service api --environment production
筛选语法(Railway 查询语言,控制面板也支持):
- 文本:不带引号的词 → 子串匹配;
"two words"→ 短语匹配。 - 级别(仅部署 / 构建):
@level:error、@level:warn、@level:info。 - HTTP 字段:
@httpStatus、@method、@path、@host、@requestId、@clientUa、@srcIp、@edgeRegion、@upstreamAddress、@upstreamProto、@downstreamProto、@responseDetails、@deploymentId、@deploymentInstanceId、@totalDuration、@responseTime、@upstreamRqDuration、@txBytes、@rxBytes、@upstreamErrors。 - 运算符:
> >= < <= ..(范围,例如@httpStatus:200..299);AND、OR、-(取反)、括号。
如果用户要求“即使部署失败,也要查看最新部署的日志”,请添加 --latest——否则 railway logs 会回溯到最近一次成功的部署;调试回归问题时通常不希望如此。
第 3 步 — 指标(检查资源状态)
如果问题可能由资源上限引起(OOM 终止、CPU 限流、出站流量激增、卷已满),请结合日志查看指标。
# Compact summary for the linked service, last hour.
railway metrics --json \
--project "$PROJECT_ID" --service api --environment production
# Specific dimensions.
railway metrics --cpu --memory --since 6h --json \
--project "$PROJECT_ID" --service api --environment production
# HTTP percentiles + RPS for a path.
railway metrics --http --path /api/users --json --since 1h \
--project "$PROJECT_ID" --service api --environment production
# Table across every service in the project.
railway metrics --all --json \
--project "$PROJECT_ID" --environment production
结合部署日志查看这些数据:内存逐渐接近服务上限后突然出现数据间断,说明发生了 OOM;CPU 持续达到 100% 且 p95 不断升高,说明发生了限流。不要做超出数据所能说明的主观解读。
第 4 步 — 变量(先只读,在授权范围内写入)
配置错误通常藏在变量中。列出变量会打印机密值——请将输出视为机密,绝不要在聊天中回显原始值,并使用 --json,以便总结(键名 + 值长度),而不是粘贴明文机密。
# Read — JSON includes raw values; redact before surfacing.
railway variable list --json \
--project "$PROJECT_ID" --service api --environment production
# Write only for the selected target within existing authorization.
railway variable set "FEATURE_FLAG=on" \
--project "$PROJECT_ID" --service api --environment production
# Setting a variable triggers a redeploy by default; add --skip-deploys
# (top-level, before the subcommand) to set without redeploying.
# Delete.
railway variable delete FEATURE_FLAG \
--project "$PROJECT_ID" --service api --environment production
先读取变量名称;只有在诊断需要时才私下检查其值。如果用户已经指定目标和更改内容,就不要再让他们重复选择。通过受支持的私密机制提供新机密;绝不要回显这些值,也不要将其放入提示词、日志或诊断命令输出中。请检查已安装 CLI 支持的标准输入/私密输入接口,不要凭空编造标志。
步骤 5 — 修复并部署
三个部署动词,按意图强度递增:
| 动词 | 效果 | 使用时机 |
|---|---|---|
railway restart | 重启最新部署,不重新构建。 | 进程卡住,但构建产物正常。 |
railway redeploy | 重新运行最新部署(或使用 --from-source 拉取最新提交 / 镜像)。 | 遇到暂时性故障,或要重新部署相同的构建产物。使用 --from-source,无需上传即可获取新提交。 |
railway up | 上传当前工作目录并部署。 | 明确选择上传部署,且不存在冲突的仓库流水线。 |
授权的手动操作的 CLI 用法(非默认 CI/CD 路径):
# Restart (no rebuild). -y skips the confirmation dialog.
railway restart -y --json \
--project "$PROJECT_ID" --service api --environment production
# Redeploy the latest deployment.
railway redeploy -y --json \
--project "$PROJECT_ID" --service api --environment production
# Redeploy and pull the newest commit / image from the configured source.
railway redeploy -y --from-source --json \
--project "$PROJECT_ID" --service api --environment production
# Upload and deploy this directory. --ci streams build logs only, then exits;
# perfect for agent sessions (no interactive log attach).
railway up --ci \
--project "$PROJECT_ID" --service api --environment production \
--message "fix: bump httpx to 0.27 to pick up TLS bug fix"
# Remove the most recent deployment (rollback to whatever was before it).
railway down -y \
--project "$PROJECT_ID" --service api --environment production
railway up --ci 是适合 Agent 使用的形式:它会启用 CI=true,将构建日志流式输出到 stdout,并在构建失败时以非零状态码退出。不使用 --ci 时,CLI 会尝试打开实时日志分页器;在自动化环境中,这会导致命令挂起。
部署后,务必验证:抽查新部署的日志和一小段指标窗口,不要只相信退出代码。Railway 构建可能成功,但运行时仍可能在启动时陷入崩溃循环。
# Quick verification loop.
railway deployment list --json --limit 3 \
--project "$PROJECT_ID" --service api --environment production
railway logs --lines 50 --since 2m \
--project "$PROJECT_ID" --service api --environment production
步骤 6 — 运行、shell、ssh、db connect
对于需要在本地使用生产环境变量的开发工作流,或需要在运行中的容器中打开 shell 的场景:
# Run a one-shot command with the linked service's variables injected.
railway run --service api --environment production -- node scripts/migrate.js
# Open a subshell with the same env (interactive — only run when the user is at the terminal).
railway shell --service api --environment production --silent
# SSH into the running container of a service. -i picks an identity file if Railway
# can't find a usable key in ~/.ssh.
railway ssh \
--project "$PROJECT_ID" --service api --environment production
# One-shot remote command (non-interactive).
railway ssh \
--project "$PROJECT_ID" --service api --environment production \
-- ls /app
# Open a database shell against a Railway-managed DB service.
railway connect postgres \
--project "$PROJECT_ID" --environment production
railway run env 和 railway run printenv 会打印该服务的所有机密变量——请像对待 railway variable list --json 的输出一样处理,切勿将其粘贴回去。
常见故障情况
Unauthorized. Please check that your RAILWAY_TOKEN is valid
检查实际命令的作用范围和已配置的身份。项目范围的凭据可能适用于读取项目,但无法列出工作区。先尝试所需的项目读取操作或等效的已认证连接器。只有在现有能力无法完成该操作时,才请求额外访问权限;切勿打印凭据内容。
构建 FAILED,部署日志为空
故障出现在 --build 日志中,而非默认部署流:
railway logs --build "$DEPLOYMENT_ID" --lines 500 \
--project "$PROJECT_ID" --service api --environment production
如果不知道部署 ID,railway deployment list --json --limit 5 会列出最近失败的部署。
部署状态为 CRASHED,部署日志以启动命令结束
应用在启动期间退出。查看 railway logs --lines 200 的末尾,获取实际异常。常见情况:
- 缺少环境变量(例如
KeyError: 'DATABASE_URL'或panic: required environment variable …)→ 使用railway variable list --json确认,然后运行railway variable set …。 - 端口绑定错误 — Railway 会设置
$PORT;服务必须绑定到0.0.0.0:$PORT,而不是硬编码的端口。 - 数据库连接被拒绝 — 检查关联的数据库服务是否位于同一环境中,并确认应用使用的私有网络 DNS(例如
postgres.railway.internal)是否正确。
构建成功,但边缘节点返回运行时 502 / Bad Gateway
应用未能在规定时间内绑定到 $PORT(默认健康检查时间窗口)。原因可能是应用启动缓慢(在 railway.json/railway.toml 中提高 healthcheckTimeout,或修复启动缓慢的问题),也可能是绑定到了 127.0.0.1 而非 0.0.0.0。使用 railway logs --http --status 502 --lines 50 交叉检查,确认问题来源是边缘节点。
突发 OOM(SIGKILL / out of memory)
结合部署日志和 railway metrics --memory --since 30m --json 一起查看。如果内存升至服务上限,且时间上与进程被终止相吻合,请提高服务的内存上限(在控制面板中设置,或修改 railway.json 的 resources.memory)。不要在不告知用户的情况下悄悄提高上限——请明确指出你发现了内存达到上限的情况。
在 Agent 会话中 railway up 挂起
你忘记了 --ci。默认模式会打开不会自动退出的实时分页器。终止它,然后使用 --ci 重新运行。
变量更改“未生效”
默认情况下,railway variable set 会触发重新部署,但如果传入了 --skip-deploys,变量只会暂存,正在运行的部署仍会使用旧值。检查待处理的更改和仓库的发布流程。只有在获得授权且符合流水线要求时,才应用更改或重新部署;不要仅仅为了强制发布代码而这样做。
约定
- 优先使用 JSON。 为每个支持该选项的命令添加
--json,并使用jq解析,而不是抓取人类可读的输出。输出格式可能会变,但 JSON 键是稳定的。 - 每次调用都明确指定范围。 在 Agent 会话中,每个命令都传入
--project、--service、--environment。不要依赖.railway/中的关联状态——用户看不到这些信息,而且状态漂移时会令人困惑。 - 默认不使用流式日志。 始终与
--lines、--since或--until搭配使用。流式输出适合在终端操作的人类,不适合 Agent。 - 绝不粘贴机密。
railway variable list、railway run env和railway shell都会显示明文机密。改为汇总信息(键名、值长度)。用户需要机密时,请使用受支持的私密交付机制;普通诊断输出中只应包含名称和安全状态。 - 保持操作范围不变。 重启、重新部署或配置操作应沿用现有授权。对于删除操作或超出该范围的操作,先确认具体意图和影响。非交互式标志不代表获得了授权。
- 部署后进行验证。 不要以
railway up --ci的成功提示作为结束。获取最新部署的状态和 50 行日志样本,让用户看到实际运行状态,而不只是构建结果。 - 每次调查只关注一种故障模式。 构建失败、崩溃循环、5xx 和 OOM 的表现各不相同,日志流也各不相同。不要把它们的日志尾部混在同一份报告中。
Onsager 附带脚本(可选,针对特定仓库)
scripts/ 目录包含三个 shell 包装脚本,专为 onsager-ai/onsager 单体仓库进行了调整。这些脚本针对该仓库的部署配置固定编写(服务名称 onsager、环境变量 ONSAGER_RAILWAY_TOKEN、生产 URL https://onsager-production.up.railway.app、justfile 目标)。Onsager 以外的仓库可以忽略这些脚本,或基于它们创建分支;上面的通用操作流程适用于所有项目。
在 Onsager 仓库中:
| 任务 | 命令 |
|---|---|
| 部署前检查 | sh scripts/preflight.sh |
| 诊断故障 | sh scripts/debug.sh [service] |
| 验证线上部署 | sh scripts/smoke.sh [url] |
preflight.sh— 在任何部署前运行,或在排查构建故障时运行。检查锁文件(Cargo.lock、pnpm-lock.yaml)是否已纳入 git 跟踪、Dockerfile 的 COPY 源是否存在、Railway 变量是否泄漏localhost,以及DATABASE_URL是否指向 Railway Postgres 插件。任何检查失败时均以非零状态码退出;未设置ONSAGER_RAILWAY_TOKEN时会跳过 Railway 变量检查。debug.sh [service]— 针对失败或卡住的部署执行一次性诊断:服务状态、构建日志(40 行)、部署/运行时日志(40 行)、仅含错误的日志(20 行)、HTTP 4xx/5xx(10 行)、仅变量名称(需要 Python 3)。默认服务为onsager。复用已配置的 CLI 身份验证;也可映射ONSAGER_RAILWAY_TOKEN。服务提供商的日志仍可能包含私有应用数据,需要私下审查。smoke.sh [base_url]— 部署后验证:通过curl检查 API(/api/health、/api/auth/me、/api/nodes、/api/sessions),并可选地通过agent-browser检查 UI(/、/sessions、/nodes、/settings)。默认 URL 为https://onsager-production.up.railway.app。如果 PATH 中没有agent-browser,则会优雅地跳过 UI 检查。
这些脚本展示了包装脚本的编写模式;其他采用此技能的仓库应复制该目录,并根据自身部署情况调整脚本内容。
相关技能
- 仓库的规范驱动开发流程技能——当修复涉及代码更改,而不只是运维操作时使用;规范/分支/PR 流程就在这里。本技能从部署步骤开始。
plan-dag——当操作人员的问题实际上是“还有什么在阻碍部署?”,而不是“部署这个东西”时使用。- Railway 自带的 AI 功能——
railway agent -p "<question>"可在 CLI 中运行交互式助手,railway mcp install可将 Railway 的 MCP 服务接入 Claude Code / Cursor / Codex。当本技能的脚本化流程不够用时,可将它们用作备用方案;但它们不能替代上文明确的 JSON 优先流程——它们适用于探索性问题,而非可复现的自动化。
人工决策
沿用已确定的决策和授权;常规实现与工具选择由 Agent 负责。仅当本流程要求人工选择、澄清或确认时,才使用当前运行环境支持的结构化提问工具,并遵循其原生说明和工具约定;通过 harness-operations 处理相关机制。明确写出具体的项目、服务、环境、操作和权衡;在收到明确答复前,等待处理依赖该答复的工作。不要只用散文描述请求。如果没有获准使用的提问工具,请说明这一限制,并通过既定的人工交接渠道处理,不要擅自假定已获批准。