一、是不是构建超时

错误信息形如:

Build timed out after 600 seconds

或:

Deploy failed: build exceeded time limit (1800s)

确认你的当前套餐:

# 在 Railway Dashboard → Settings → Plan
套餐Build Timeout
Trial10 分钟(600s)
Hobby30 分钟(1800s)
Pro60 分钟(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 自动构建:

  1. 检测语言(Node / Python / Go / Ruby / etc.)
  2. 下载 Nix 包(首次 30-90 秒)
  3. 拉取 base image
  4. 执行 install 命令
  5. 执行 build 命令
  6. 推送到 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 的稳定线路能保证多平台部署调试不掉线。

六、相关报错