デプロイ

GitHub Actions経由でアプリがRailwayのステージングと本番に出荷される仕組み。

デプロイは完全に自動化されています。コミットしてPRを開けば、プレビューURL付きでステージングに反映されます。mainにマージすれば本番に反映されます。ここでは裏で何が起きているかを説明し、うまくいかないときに何をすべきかが分かるようにします。

アーキテクチャ

  • 1つのRailwayプロジェクト — プラットフォーム境界(認証、ネットワーク)。
  • N個のRailwayサービスapps/*の各アプリに1つ。各サービスは独立してデプロイされる。
  • Railpackがアプリをビルド(設定不要)。ルートのpnpm-workspace.yamlを読み、対象アプリとその依存関係だけをビルド。

アプリごとの配線

各アプリには3つが必要です:

  1. apps/<app-name>/deploy.config.yml — Railwayサービスを指し、環境変数マッピングを宣言。
  2. .github/workflows/deploy-app-<app-name>-staging.yml — 手動のworkflow_dispatchワークフロー(単発のステージングデプロイ用。PRで走るのはこれではありません — 次のセクション参照)。
  3. .github/workflows/deploy-app-<app-name>-production.ymlmainへのpushでパスフィルタ付きで起動。ほとんどのアプリはapps/<app-name>/** + shared/database/**でフィルタしますが、共有コードへの依存が広い一部のアプリ(vibe-coding-guide, staff-portalなど)は代わりにshared/**でフィルタします。どちらかはアプリのワークフローファイルで確認してください。

両方のアプリワークフローは共有の.github/workflows/deploy-reusable.ymlを呼び出し、そこで実際の処理を行います: pnpm install --frozen-lockfile → 必要ならtest → pnpm --filter <app> buildrailway up

デプロイの2つの経路

ステージング(PRを開いたとき)

単一のワークフローpr-preview-neon.ymlが、プレビュー全体を統括します:

  1. フィーチャーブランチにpushし、mainへのPRを開く。
  2. スキーマが変わっていれば、マイグレーションを生成してPRにコミットバック。
  3. PRごとに1つのNeon DBブランチを作成(preview/pr-<番号>-<ブランチ>)、14日で失効、マイグレーション適用済み。
  4. pr-preview-neon.ymlが変更されたアプリを検出し、マトリックスジョブで各アプリについてdeploy-reusable.yml直接呼び出します — アプリごとのステージングワークフローはディスパッチされません。
  5. 変更された各アプリはRailwayのステージング環境にデプロイされ、共有のNeon PRブランチに接続されます。
  6. 影響のある各アプリのプレビューURLがPRコメントに投稿されます。

Neon PRブランチはPRクローズ時に削除されます。

本番(マージしたとき)

  1. PRをmainにマージ。
  2. 影響のある各アプリの本番ワークフローがパスフィルタ経由で起動。
  3. マイグレーションがNeon mainに適用される。
  4. Railwayが本番サービスを再デプロイ。

コードにシークレットが見えない理由

Railwayの環境変数は、再利用可能なワークフローがデプロイ時に注入します。ワークフローはapps/<your-app>/deploy.config.ymlsecrets:ブロックを読み、GitHubのsecret/varsから値を取得してRailwayサービス環境にpushします。詳しいマッピングは環境変数を参照。

ログ

Railwayはstdoutとstderrのみをキャプチャします。console.log, console.warn, console.errorを使います。本番ではフィールドで検索できるようJSONでログを出します:

構造化ログtypescript
console.error(JSON.stringify({
level: 'error',
event: 'api_error',
error: error instanceof Error ? error.message : 'Unknown',
timestamp: new Date().toISOString(),
}));

PII(メール、名前)やシークレットは絶対にログしないでください。ログをファイルやデータベースに書き込まないでください。

自動注入される変数

以下は宣言不要です — プラットフォームが設定します:

  • DATABASE_URL — 環境のデータベースサービスから注入。
  • AUTH_UI_URL — 非認証サービスすべてに注入。

Claudeに聞く

新しいアプリをデプロイパイプラインに追加
Claudeプロンプト
テンプレートからmeal-plannerという新しいアプリをスキャフォルドしました。Railwayの deploy.config.yml と2つのGitHub Actionsワークフローファイル(deploy-app-meal-planner-staging.yml と deploy-app-meal-planner-production.yml)を作成してください。apps/checkin-board/をリファレンスにしてください。

デプロイが失敗したとき

  • GitHub Actionsのワークフロー実行画面でどのステップが失敗したか確認。
  • Lint/型チェック失敗 → ローカルでpnpm build:<your-app>を実行して再現。
  • railway up失敗 → Railwayダッシュボードを開く、サービスログに原因が出ていることが多い。
  • 環境変数の欠損 → 環境変数を参照。
  • マイグレーション失敗 → データベースマイグレーションエラーを参照。

クイズ

Quiz

`apps/meal-planner/`配下のファイルだけを変更したPRを`main`にマージしました。どの本番サービスが再デプロイされますか?