株式会社renue
AI導入・DXの悩みをプロに相談してみませんか?
AIやDXに関する悩みがありましたら、お気軽にrenueの無料相談をご利用ください。 renueのAI支援実績、コンサルティングの方針や進め方をご紹介します。
デプロイが通らない——6ステージのどこで止まっているかを特定せよ
「デプロイが動かない」「本番に反映されない」——この報告を受けたとき、最初にやるべきことは6ステージのどこでコケているかを特定することです。闇雲にログを見たり、再デプロイを繰り返しても問題は解決しません。
ある開発チームのリーダーは、デプロイトラブルに直面した新人エンジニアにこう伝えました。「デプロイやインフラ周りは事故対応して覚えるしかない。起こるたびに理解するようにしていこう」——そして、以下の6ステージフレームワークを共有しました。
デプロイの6ステージ
1. PR立てる 2. PRマージ 3. ビルド 4. デプロイ 5. イメージpull 6. 再起動
デプロイ障害の切り分けは、この6ステージのどこで止まっているかを上から順に確認することが基本です。
各ステージの典型的な障害パターン
ステージ1-2:PRとマージ
| 障害 | 原因 | 対策 |
|---|---|---|
| マージできない | コンフリクトが発生している | ベースブランチを最新化してコンフリクト解消 |
| CIが通らない | テスト失敗・lint エラー | ローカルでCI相当のチェックを実行してから push |
ステージ3:ビルド
ビルドは最も障害が発生しやすいステージです。
| 障害 | 原因 | 対策 |
|---|---|---|
| ビルド失敗 | CIが不十分でビルド不可能なマージが通った | CI にビルドチェックを追加 |
| 依存解決エラー | パッケージ追加やDockerfile編集時に発生しがち | lockfile を更新してコミット |
| ローカルで成功するがCIで失敗 | ベースイメージ・OS・環境変数の差異 | ベースイメージをダイジェストでピン留め |
| リソース不足 | CPU/メモリ/ディスク制約でOOMやファイル書き込みエラー | ビルドエージェントのリソースを確認・拡張 |
ステージ4:デプロイ
| 障害 | 原因 | 対策 |
|---|---|---|
yarn build成功だがデプロイ失敗 | デプロイ環境固有のエラー | デプロイログを確認し環境差分を特定 |
| マイグレーション失敗 | DB スキーマ変更が既存データと衝突 | マイグレーションの冪等性を確保 |
ステージ5:イメージpull
| 障害 | 原因 | 対策 |
|---|---|---|
| イメージが見つからない | push先のACR/ECRとVM参照先が異なる | レジストリURLの一致を確認 |
| キャッシュで古いイメージが使われる | latestタグ固定でキャッシュが残る | git commit SHAタグも付与し追跡可能に |
| ディスク容量不足 | 旧イメージが残りディスクを圧迫 | pull前にdocker image pruneで整理 |
| 認証エラー | ACR/ECRのトークン期限切れ | pull前にdocker loginを再実行 |
実際に、VM上に旧ACRの不要イメージが約29GB残存し、ディスク使用率87%(残り8.5GB)でpullが失敗した事例が報告されています。
ステージ6:再起動
| 障害 | 原因 | 対策 |
|---|---|---|
| 自動再起動しない | Webhookの設定が不十分 | デプロイフック/Webhookの設定を確認 |
| 起動後にエラー | マイグレーション自動実行でサーバー起動失敗 | マイグレーションと起動を分離 |
| ヘルスチェック通過だが機能エラー | ヘルスチェックがDB接続を含まない | ヘルスチェック内容を拡充、ログでstartup_diagnosticsを確認 |
特に注意すべきは「ヘルスチェックが通っているのにコア機能が動かない」パターンです。/healthがDB接続チェックを含まない場合、「画面は表示されるが変換機能がエラー」という状態になります。
切り分けの実践手順
ステップ1:直近のGitHub Actionsを確認
まずCI/CDパイプラインのログを確認し、ステージ1-4のどこで止まっているかを特定します。
ステップ2:コンテナの状態を確認
docker compose ps # コンテナの状態(Up/Exited) docker compose logs --tail=30 # 直近のログ
Up状態でもログにエラーが出ている場合は、ステージ6の問題です。
ステップ3:疎通テスト
curl http://localhost:3000 # FE → 200 or 302 curl http://localhost:8000/health # BE → healthy curl http://localhost:3000/api/health # FE→BE → 200
FE単体は通るがFE→BEが通らない場合は、Docker Composeのサービス間ネットワーク設定を確認します。
ステップ4:Bastionトンネルでブラウザ確認
閉域VM環境では、Bastionトンネル経由でブラウザからアクセスし、画面表示だけでは検知できない問題を拾います。
イメージタグ戦略:latestの罠
Docker イメージをlatestタグだけで管理すると、「どのコミットがデプロイされているかわからない」状態になります。
推奨タグ戦略
docker build \
-t registry.example.com/app:latest \
-t registry.example.com/app:${GIT_SHA} \
.
latestに加えてgit commit SHAのタグも付与することで、どのコミットがデプロイされたか追跡でき、ロールバック時にも使えます。
ダウンタイム最小化のデプロイ手順
本番環境でのコンテナ更新では、ダウンタイムを最小化する手順が重要です。
- 新イメージをpull(旧コンテナ稼働中):pull失敗時は旧コンテナが動いたまま→影響なし
- 旧コンテナを停止・削除:ここからダウンタイム開始
- 新コンテナを起動:ダウンタイム終了
- 旧イメージを回収:
docker image prune -fでディスク解放
pullを停止前に実行することで、ダウンタイムを「コンテナ停止→起動」の数十秒に短縮できます。
Apple Silicon環境の罠
Apple Silicon(M1/M2/M3)のMacでビルドしたイメージは、Linux AMD64のVMでは動作しません。必ず--platform linux/amd64を指定してビルドする必要があります。
docker build --platform linux/amd64 -t registry/app:latest .
このオプションを忘れると、VMにpullは成功するがコンテナ起動時にエラーになるという、発見しにくい障害が発生します。
まとめ:デプロイ障害切り分けチェックリスト
| ステージ | 確認項目 | よくある原因 |
|---|---|---|
| 1. PR | PRが作成できているか | ブランチ保護ルール、権限不足 |
| 2. マージ | コンフリクトなくマージできたか | コンフリクト、CI不通過 |
| 3. ビルド | GitHub Actionsが成功しているか | 依存解決エラー、Dockerfile変更 |
| 4. デプロイ | デプロイジョブが成功しているか | マイグレーション失敗、環境差分 |
| 5. pull | 正しいイメージがpullできているか | レジストリURL不一致、ディスク不足、認証切れ |
| 6. 再起動 | コンテナがUp+ログにエラーなしか | Webhook未設定、ヘルスチェック不足 |
デプロイ障害は「事故対応して覚える」ものです。しかし、6ステージフレームワークを知っていれば、パニックにならず体系的に切り分けができます。次にデプロイが止まったとき、この6ステージのどこかを必ず確認してください。
関連記事:障害対応・開発プロセスの完全ガイド
障害対応・インフラ連載として、以下の記事も合わせてお読みください。
- エラー読解:エラーメッセージ読解術|まず簡単な方から試す
- マイグレーション:マルチORM環境のDBマイグレーション管理
- 閉域デプロイ:閉域ネットワーク環境へのAIアプリデプロイ完全ガイド
- Gitワークフロー:AIエージェント時代のGitワークフロー設計
- ポストモーテム:AI開発プロジェクトのポストモーテム設計
AI開発のインフラ・デプロイでお悩みの方は、renueにご相談ください。

