インフラ・運用 2026.04.23

本番デプロイが怖い!ゼロダウンタイムリリースの実践手順

約4分で読めます

「本番に上げるたびに手が震える」そんな経験はありませんか?ゼロダウンタイムデプロイの仕組みと実践手順を、Laravel・Next.jsの具体例とともに解説します。

「デプロイ、怖いな」と感じたことはありませんか?

こんな悩みを抱えているエンジニアやWeb担当者の方は多いのではないでしょうか。

  • git pull してから php artisan migrate を叩くまでの数十秒、サービスが落ちている気がする
  • デプロイのたびにユーザーからエラーの報告が来る
  • 金曜の夕方にリリースして、週末に障害対応することになった
  • ロールバックの手順が曖昧で、本番トラブル時に焦ってしまう

「デプロイ=怖いもの」という認識は、手順が整備されていない環境では当然の感覚です。しかし適切な仕組みを導入すれば、デプロイはルーティンの作業へと変わります。この記事では、ゼロダウンタイムデプロイの考え方と、実際のプロジェクトで使える具体的な実装手順を解説します。


なぜデプロイ中にダウンタイムが発生するのか

まず、従来型の「怖いデプロイ」がなぜ危険なのかを整理しましょう。

典型的なデプロイ手順はこうです。

# よくある「怖いデプロイ」の流れ
git pull origin main
composer install
npm run build
php artisan migrate      # ← ここでDBの状態が変わる
php artisan cache:clear
systemctl restart php-fpm

この手順の問題点は、コードの更新とDB変更がアトミックに行われないことです。git pull でコードが最新になった瞬間から migrate が完了するまでの間、旧コードと新スキーマ、または新コードと旧スキーマが混在する「中間状態」が生まれます。この数秒〜数十秒の間にリクエストが来ると、予期しないエラーが発生します。

さらに php-fpm の再起動中は新規リクエストが受け付けられず、ユーザーには502エラーが返ります。トラフィックの少ない深夜にデプロイするのはこのためですが、それ自体がエンジニアの負担になっています。

flowchart TD
    A[git pull 実行] --> B[新旧コード混在期間]
    B --> C[composer install]
    C --> D[マイグレーション実行]
    D --> E[⚠️ 新コード+旧スキーマの危険な瞬間]
    E --> F[php-fpm 再起動]
    F --> G[502エラー発生帯]
    G --> H[デプロイ完了]

この構造的な問題を解決するのが、ブルーグリーンデプロイや**シンボリックリンク方式(Deployer方式)**です。


サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

実践:Deployerを使ったゼロダウンタイムデプロイ

Deployerとは

DeployerはPHP製のデプロイツールで、Laravelプロジェクトとの相性が抜群です。仕組みの核心は「シンボリックリンクの切り替え」にあります。新しいリリースを別ディレクトリに完全に準備してから、最後の一瞬にリンクを切り替えるため、切り替え中の「中間状態」が事実上ゼロになります。

/var/www/myapp/
├── current -> releases/20240601_120000/  ← Nginxはここを見ている
├── releases/
│   ├── 20240601_120000/  ← 現在稼働中
│   └── 20240601_115500/  ← 前バージョン(ロールバック用)
└── shared/
    ├── .env
    └── storage/

インストールと基本設定

# Composerでインストール
composer require --dev deployer/deployer

# Laravel用テンプレートで初期化
./vendor/bin/dep init

生成される deploy.php を実案件に合わせて設定します。

<?php
// deploy.php
namespace Deployer;

require 'recipe/laravel.php';

// プロジェクト設定
set('application', 'my-laravel-app');
set('repository', '[email protected]:yourorg/your-repo.git');
set('branch', 'main');
set('keep_releases', 5);  // 過去5世代を保持

// shared_files: リリース間で共有するファイル
set('shared_files', ['.env']);
set('shared_dirs', ['storage']);

// writable: Webサーバーに書き込み権限を付与するディレクトリ
set('writable_dirs', ['bootstrap/cache', 'storage']);

// 本番サーバーの設定
host('production')
    ->set('hostname', 'your-server.example.com')
    ->set('remote_user', 'deploy')
    ->set('deploy_path', '/var/www/myapp');

// デプロイ後のタスク定義
after('deploy:failed', 'deploy:unlock');

// マイグレーションを安全なタイミングで実行
task('deploy:migrate', function () {
    run('cd {{release_path}} && {{bin/php}} artisan migrate --force');
});

// タスクの順序(重要)
after('deploy:update_code', 'deploy:migrate');

デプロイの実行

# 本番へのデプロイ(これだけ!)
./vendor/bin/dep deploy production

# ロールバックも一発
./vendor/bin/dep rollback production

Deployerは内部でコードのクローン、依存パッケージのインストール、マイグレーション、キャッシュクリアを順番に実行し、すべてが成功した時点でシンボリックリンクを切り替えます。途中でエラーが発生した場合は自動的にロールバックされるため、中途半端な状態で本番が壊れることがありません。


実案件での話:深夜リリースから昼間リリースへ

ある神奈川県内のEC事業者様のケースをご紹介します。Laravelで構築された受発注システムで、月に2〜3回のリリースがあるプロジェクトでした。

課題: デプロイのたびに「念のため深夜2時に作業」というルールが慣習化しており、担当エンジニアの疲弊が深刻でした。手順書もなく、コマンドをターミナルに直打ちしていたため、過去に一度ヒューマンエラーで本番DBのマイグレーションが中断し、数時間の障害が発生した経験がありました。

解決策: Deployerの導入とGitHub Actionsとの連携。main ブランチへのマージをトリガーにCIが走り、テスト通過後に自動でステージング環境へデプロイ。本番へのデプロイはSlackの承認ボタン一押しで実行できる体制を構築しました。

結果: 深夜作業がゼロになり、デプロイは平日昼間に実施できるようになりました。ロールバックも dep rollback production 一発で完了するため、万一の際の復旧時間が大幅に短縮されています。


よくある失敗パターンと対処法

カラム名の変更や削除を一度のデプロイでやろうとすると、切り替え後の旧コードが新スキーマを読めずにエラーになります。**「展開(Expand)→ 移行 → 収縮(Contract)」の3段階デプロイ**が鉄則です。例えばカラム名を `user_name` から `full_name` に変えるなら、①両方のカラムを持つ状態でリリース → ②コードを新カラム参照に切り替え → ③旧カラムを削除、という順序を踏みます。
Deployerでよくあるミスです。`.env` や `storage` ディレクトリを `shared_files` / `shared_dirs` に明示的に登録しないと、リリースごとに消えてしまいます。初回セットアップ時に必ず確認しましょう。
`opcache.validate_timestamps=0` の本番設定でコードをデプロイしても、OPcacheが古いコードをキャッシュし続けることがあります。Deployerには `artisan:optimize` タスクが含まれますが、必要に応じて `cachetool` などでOPcacheをリセットするタスクを追加してください。
`migrate:rollback` は `down()` メソッドの実装が前提ですが、実務ではサボりがちです。スキーマ変更を伴うリリースでは必ず `down()` を書く習慣をチームに根付かせるか、「後方互換マイグレーション」で設計して `rollback` に頼らない構成を検討してください。

サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

サーバー管理、丸ごとお任せください

サーバー保守・運用

監視・障害対応・パフォーマンス改善まで、安定稼働をサポートします

200件以上の制作実績 顧客満足度97% 初回相談無料

※ 通常1営業日以内にご返信します

まとめと次のステップ

ゼロダウンタイムデプロイは「大企業の贅沢な仕組み」ではありません。Deployerを使えば、中規模のLaravelプロジェクトでも数時間で導入できます。一度仕組みを整えると、デプロイの心理的コストが劇的に下がり、リリース頻度を上げやすくなります。それがサービス改善のサイクルを加速させることにつながります。

まず取り組むべきステップは以下の通りです。

Deployerの設定ファイルの書き方やGitHub Actionsとの連携について「自社の環境に当てはめるとどうなるか」が判断しにくい場合は、ぜひFivenine Designにご相談ください。既存の構成を拝見した上で、無理のない移行プランをご提案します。

この記事をシェア

サーバー・インフラの課題を解決します

構築・移行・監視・障害対応まで、安定した運用環境をご提供します。 初回相談は無料です。

※ 1営業日以内にご返信いたします

この技術でお困りなら

無料でプロに相談できます

相談する
AIに無料相談