一、是不是构建超时
错误信息形如:
Build timed out after 600 seconds
或:
Deploy failed: build exceeded time limit (1800s)
确认你的当前套餐:
# 在 Railway Dashboard → Settings → Plan
| 套餐 | Build Timeout |
|---|---|
| Trial | 10 分钟(600s) |
| Hobby | 30 分钟(1800s) |
| Pro | 60 分钟(3600s) |
| Enterprise | 自定义 |
二、处理路径
先看 build 时间分布
在 Railway Dashboard 的 Build Logs 中,按时间戳查看:
[00:00] Cloning repository → 1-30s
[00:10] Detecting Nixpacks language → 5-15s
[00:15] Setting up environment → 10-30s
[00:30] Installing dependencies (npm) → 60-600s ← 通常最慢
[05:00] Building application → 30-300s
[06:00] Pushing image → 30-120s
[07:00] Deploying → 5-30s
90% 的 timeout 在「Installing dependencies」阶段。
换包管理器
# 项目根目录
# 如果有 package-lock.json
rm package-lock.json
npm install -g pnpm
pnpm install
# pnpm-lock.yaml 提交到 git
pnpm 通过 hard link / symlink 模式安装依赖,比 npm 快 30-50%。
跳过不必要的 postinstall
某些库的 postinstall 下载二进制(如 puppeteer 下载 Chrome),构建容器内不需要:
# Railway 项目 Settings → Environment Variables
PUPPETEER_SKIP_DOWNLOAD=true
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
NODE_ENV=production # 跳过 devDependencies
或者 package.json 中:
{
"scripts": {
"postinstall": "echo skip"
}
}
自定义 Dockerfile(multi-stage)
# Dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile --prod
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/.next ./.next
COPY package.json ./
CMD ["node", "server.js"]
multi-stage 把 production node_modules 和 build artifacts 分开,最终镜像更小,layer cache 也更友好。
升 Pro 套餐
如果业务确实需要长 build(如 Rust 编译、Python ML 模型下载),$20/月 Pro 套餐把 timeout 提到 60 分钟。
三、为什么会 timeout(原理)
Railway 使用 Nixpacks 自动构建:
- 检测语言(Node / Python / Go / Ruby / etc.)
- 下载 Nix 包(首次 30-90 秒)
- 拉取 base image
- 执行 install 命令
- 执行 build 命令
- 推送到 Container Registry
慢点分布:
- 首次 cold build:Nixpacks 元数据下载(5-90 秒)
- 重复 build:缺乏 layer cache 时每次都重装依赖
- Native module:从源码编译需要 C++ 编译时间
怎么确认是代码问题还是平台限制?
4.1 启用 build cache
Railway 默认有 layer cache,但需要正确的 Dockerfile 结构:
# ❌ 不利于 cache
COPY . .
RUN pnpm install
RUN pnpm build
# ✅ 利于 cache(先 install,再 build)
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
4.2 减少依赖
npm-check-unused 找无用依赖:
npx depcheck
很多 indie 项目里都有 5-20 个未使用的依赖。
4.3 把重计算移出 build
像 Prisma migrate / Database seed 不应该在 build 阶段:
# ❌ 写在 build script 里
"build": "prisma migrate deploy && next build"
# ✅ 写在 deploy script 里
"build": "next build",
"start": "prisma migrate deploy && node server.js"
五、如果## 以上都试过了,下一步查什么?
5.1 切到 Fly.io / Render
Fly.io 默认 build timeout 1 小时(免费)+ 国内访问尚可。Render 默认 25 分钟(免费)+ 75 分钟(付费)。如果 Railway 仍超时可考虑迁移。
5.2 自托管在 VPS
如果 build 复杂度极高(Rust / ML),考虑自托管:
- Hetzner CX11(€4/月)
- DigitalOcean Basic Droplet($6/月)
- Build 时长不限
5.3 跨境环境检查
调试 Railway 部署 + 多平台切换(Vercel / Render / Fly.io)需要稳定访问多个 Dashboard。
如果你需要同时管 Railway / Vercel / GitHub Actions / Stripe 等海外服务,配一条海外服务跑 GitHub Actions / Cloudflare 的稳定线路能保证多平台部署调试不掉线。