Deployerで複数サイトを管理(3)コードリリース

今回はDeployerの中心目的であるゼロダウンタイムのデプロイについてです。目的はアプリの変更のインストール(コードリリース)をサイトをダウンさせることなく完了させることであり、万が一問題があれば前の変更に1つのコマンドの実行でもとに戻せるという大役のタスクです。

今回はDeployerの中心目的であるゼロダウンタイムのデプロイについてです。目的はアプリの変更のインストール(コードリリース)をサイトをダウンさせることなく完了させることであり、万が一問題があれば前の変更に1つのコマンドの実行でもとに戻せるという大役のタスクです。

コード変更リリースのメカニズム

dep deployがDeployerのコード変更リリースのコマンドですが、その実行によりプロジェクトのディレクトリー構造が変わり、それゆえにApacheやngnixのウェブサーバーの設定の変更も必要とされます。複雑な感じですが、メカニズムはシンプルです。

まず、dep deploy実行後のLaravelのディレクトリ構造を見てみましょう。 対象となるホストのディレクトリは空という仮定です。

├── current -> releases/1
├── releases
│   └── 1
│       ├── app
│       ├── bootstrap
│       ├── config
│       ├── database
│       ├── lang
│       ├── public
│       ├── resources
│       ├── routes
│       ├── src
│       ├── storage -> ../../shared/storage
│       ├── tests
│       ├── utils
│       └── vendor
│       └── .env -> ../../shared/.env
└── shared
    └── storage
        ├── app
        ├── debugbar
        ├── framework
        └── logs
        └── .env

上のディレクトリーツリーにおいて、releases/1のディレクトリがLaravelのプロジェクトのルートとなり見てのようにすべてのアプリのファイルがそこにインストールされます。そして次のコードリリースがdep deployで実行されると、releases/2が作成され再度必要なすべてのアプリのファイルがそこにインストールされます。vendorのディレクトリ中のファイルもcomposerでインストールされるのでリリースがかさむと結構なディスク容量が必要になりますが、デフォルトの設定では最新の5つのリリースをキープしてそれより古いリリースは削除されます。

リリース毎にプロジェクトのディレクトリが変わるのは、currentというシンボリックリンクを通してそれがポイントするディレクトリを変えていきます。ということは、ウェブサーバーでは、current/publicがサイトのルートディレクトリということになります。設定の変更はそこのみです。

そして、リリースのディレクトリ内容をすべて用意してから最後にcurrentがポイントするリリースディレクトリを変えるのでゼロダウンタイムのデプロイが可能となります。

しかしながら、storageのディレクトリや.envなどリリース間でキープするべきものがあります。それらは、releasesのディレクトリからシンボリックリンクしてsharedの中で管理しリリース間で共有します。

以上がDeployerを使用したデプロイの仕組みです。

deployで実行されるタスク

以下がdep initの実行で作成されたdeployer.phpの中身とします。 前回と違って、require ‘recipe/laravel.php’とレシピがlaravelになっていることに注意を。レシピはLarvelだけでなく他のフレームワークも用意されています。

deploy.php
namespace Deployer;

require 'recipe/laravel.php';

// Config

set('repository', 'git@github.com:larajapan/example.git');

add('shared_files', []);
add('shared_dirs', []);
add('writable_dirs', []);

// Hosts

host('www.larajapan.com')
    ->set('remote_user', 'deployer')
    ->set('deploy_path', '~/example');

// Hooks

after('deploy:failed', 'deploy:unlock');

この設定で、dep deployはLaravelのプロジェクトはいったいどのようなタスクを実行するのかというと、

$ dep deploy --plan
┌──────────────────────┐
│ www.larajapan.com    │
├──────────────────────┤
│ deploy:info          │
│ deploy:setup         │
│ deploy:lock          │
│ deploy:release       │
│ deploy:update_code   │
│ deploy:env           │
│ deploy:shared        │
│ deploy:writable      │
│ deploy:vendors       │
│ artisan:storage:link │
│ artisan:optimize     │
│ artisan:migrate      │
│ deploy:symlink       │
│ deploy:unlock        │
│ deploy:cleanup       │
│ deploy:success       │
│ artisan:reload       │
└──────────────────────┘

17ものタスクから構成されることがわかります。

以下はそれぞれのタスクの説明です。

# タスク 説明
1 deploy:info デプロイ情報(リビジョン・ホスト名等)を表示
2 deploy:setup 初回デプロイ時にリリース用ディレクトリ構造(releases、shared、current)を準備
3 deploy:lock 同時デプロイを防止するためにロックファイルを作成
4 deploy:release 新しいリリース用ディレクトリを作成し、リリース番号を採番
5 deploy:update_code Git リポジトリから最新コードを取得し、新しいリリースディレクトリに配置
6 deploy:env .env ファイルを配置・設定
7 deploy:shared リリース間で共有するファイル・ディレクトリ(storage、.env など)にシンボリックリンクを作成
8 deploy:writable アプリケーションが書き込み可能とする必要のあるディレクトリのパーミッションを設定
9 deploy:vendors composer install を実行して PHP の依存パッケージをインストール
10 artisan:storage:link php artisan storage:link を実行し、public/storage のシンボリックリンクを作成
11 artisan:optimize php artisan optimize を実行し、フレームワークのブートファイルをキャッシュ
12 artisan:migrate php artisan migrate を実行し、データベースマイグレーションを適用
13 deploy:symlink current シンボリックリンクを新しいリリースに切り替え、本番反映
14 deploy:unlock デプロイロックを解除
15 deploy:cleanup 古いリリースを削除し、ディスク容量を節約
16 deploy:success デプロイ成功メッセージを表示
17 artisan:reload 稼働中のサービス(PHP-FPM 等)をリロードし、新コードを反映

リリース後

リリースした後において、リリースの現状を見たいなら、

$ dep releases

+---------------------+-------------+------------+--------+------------------------------------------+
| Date (UTC)          | Release     | Author     | Target | Commit                                   |
+---------------------+-------------+------------+--------+------------------------------------------+
| 2026-05-13 02:49:08 | 1           | Kenji Hino | HEAD   | 9b306276db4f0a644bfd23fa9103a91b5a271d81 |
| 2026-05-14 02:49:53 | 2 (current) | Kenji Hino | HEAD   | 9b306276db4f0a644bfd23fa9103a91b5a271d91 |
+---------------------+-------------+------------+--------+------------------------------------------+

前回のリリースをロールバックしたいなら、

$ dep rollback

task rollback
[www.larajapan.com] Current release is 2.
[www.larajapan.com] Rolling back to 1 release.
[www.larajapan.com] rollback to release 1 was successful

とすればリリース2からリリース1に戻ります。

確認をすると、

$ dep releases

+---------------------+-------------+------------+--------+------------------------------------------+
| Date (UTC)          | Release     | Author     | Target | Commit                                   |
+---------------------+-------------+------------+--------+------------------------------------------+
| 2026-05-13 02:49:08 | 1 (current) | Kenji Hino | HEAD   | 9b306276db4f0a644bfd23fa9103a91b5a271d81 |
| 2026-05-14 02:49:53 | 2 (bad)     | Kenji Hino | HEAD   | 9b306276db4f0a644bfd23fa9103a91b5a271d91 |
+---------------------+-------------+------------+--------+------------------------------------------+
Hugo で構築されています。
テーマ StackJimmy によって設計されています。