#はじめに
Laravel Envoy は、リモートサーバーでよく実行する共通タスクを実行するためのツールです。Blade スタイルの構文を使って、デプロイや Artisan コマンドなどのタスクを簡単に設定できます。現在、Envoy は Mac と Linux のみをサポートしていますが、Windows は WSL2 を使うことで対応可能です。
#インストール
まず、Composer パッケージマネージャーを使って Envoy をプロジェクトにインストールします:
composer require laravel/envoy --dev
Envoy をインストールすると、Envoy のバイナリがアプリケーションの vendor/bin ディレクトリに配置されます:
php vendor/bin/envoy
#タスクの作成
#タスクの定義
タスクは Envoy の基本的な構成要素です。タスクは、呼び出されたときにリモートサーバー上で実行すべきシェルコマンドを定義します。例えば、アプリケーションのキューワーカーサーバー全てで php artisan queue:restart コマンドを実行するタスクを定義できます。
すべての Envoy タスクは、アプリケーションのルートにある Envoy.blade.php ファイルに定義してください。以下はその例です:
@servers(['web' => ['[email protected]'], 'workers' => ['[email protected]']])
@task('restart-queues', ['on' => 'workers'])
cd /home/user/example.com
php artisan queue:restart
@endtask
ファイルの先頭に @servers の配列が定義されており、タスク宣言の on オプションでこれらのサーバーを参照できます。@servers 宣言は必ず1行で記述してください。@task 宣言内には、タスクが呼び出されたときにサーバー上で実行するシェルコマンドを記述します。
#ローカルタスク
サーバーの IP アドレスを 127.0.0.1 に指定することで、スクリプトをローカルコンピュータ上で実行させることができます:
@servers(['localhost' => '127.0.0.1'])
#Envoy タスクのインポート
@import ディレクティブを使うと、他の Envoy ファイルをインポートして、そのストーリーやタスクを自分のものに追加できます。インポート後は、あたかも自分の Envoy ファイルに定義されているかのようにタスクを実行できます:
@import('vendor/package/Envoy.blade.php')
#複数サーバー
Envoy では複数のサーバーにまたがってタスクを簡単に実行できます。まず、@servers 宣言に追加のサーバーを定義します。各サーバーにはユニークな名前を付けてください。追加したサーバーはタスクの on 配列にリストアップできます:
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
@task('deploy', ['on' => ['web-1', 'web-2']])
cd /home/user/example.com
git pull origin {{ $branch }}
php artisan migrate --force
@endtask
#並列実行
デフォルトでは、タスクは各サーバーで順番に実行されます。つまり、最初のサーバーでタスクが完了してから次のサーバーで実行されます。複数サーバーで並列にタスクを実行したい場合は、タスク宣言に parallel オプションを追加してください:
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
@task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
cd /home/user/example.com
git pull origin {{ $branch }}
php artisan migrate --force
@endtask
#セットアップ
Envoy タスクを実行する前に任意の PHP コードを実行したい場合は、@setup ディレクティブを使って PHP コードのブロックを定義できます:
@setup
$now = new DateTime;
@endsetup
タスク実行前に他の PHP ファイルを読み込みたい場合は、Envoy.blade.php ファイルの先頭で @include ディレクティブを使えます:
@include('vendor/autoload.php')
@task('restart-queues')
# ...
@endtask
#変数
必要に応じて、Envoy タスクに引数を渡すことができます。コマンドラインで Envoy を呼び出す際に指定してください:
php vendor/bin/envoy run deploy --branch=master
タスク内では Blade の「echo」構文でオプションにアクセスできます。また、Blade の if 文やループもタスク内で使えます。例えば、git pull コマンドを実行する前に $branch 変数の存在を確認する例です:
@servers(['web' => ['[email protected]']])
@task('deploy', ['on' => 'web'])
cd /home/user/example.com
@if ($branch)
git pull origin {{ $branch }}
@endif
php artisan migrate --force
@endtask
#ストーリー
ストーリーは複数のタスクをひとまとめにして、便利な名前でグループ化します。例えば、deploy ストーリーは update-code と install-dependencies タスクを定義内でリストアップして実行できます:
@servers(['web' => ['[email protected]']])
@story('deploy')
update-code
install-dependencies
@endstory
@task('update-code')
cd /home/user/example.com
git pull origin master
@endtask
@task('install-dependencies')
cd /home/user/example.com
composer install
@endtask
ストーリーを定義したら、タスクと同じように呼び出せます:
php vendor/bin/envoy run deploy
#フック
タスクやストーリーの実行時に、複数のフックが実行されます。Envoy がサポートするフックは @before、@after、@error、@success、@finished です。これらのフック内のコードはすべて PHP として解釈され、リモートサーバーではなくローカルで実行されます。
これらのフックは好きなだけ定義できます。Envoy スクリプト内に現れる順番で実行されます。
#@before
各タスク実行の前に、Envoy スクリプトで登録されたすべての @before フックが実行されます。@before フックは実行されるタスク名を受け取ります:
@before
if ($task === 'deploy') {
// ...
}
@endbefore
#@after
各タスク実行の後に、Envoy スクリプトで登録されたすべての @after フックが実行されます。@after フックは実行されたタスク名を受け取ります:
@after
if ($task === 'deploy') {
// ...
}
@endafter
#@error
タスクが失敗した場合(終了コードが 0 より大きい場合)、Envoy スクリプトで登録されたすべての @error フックが実行されます。@error フックは実行されたタスク名を受け取ります:
@error
if ($task === 'deploy') {
// ...
}
@enderror
#@success
すべてのタスクがエラーなく実行された場合、Envoy スクリプトで登録されたすべての @success フックが実行されます:
@success
// ...
@endsuccess
#@finished
すべてのタスクが実行された後(終了ステータスにかかわらず)、すべての@finishedフックが実行されます。@finishedフックには完了したタスクのステータスコードが渡され、その値はnullまたは0以上のintegerになります:
@finished
if ($exitCode > 0) {
// タスクのいずれかでエラーが発生しました...
}
@endfinished
#タスクの実行
アプリケーションの Envoy.blade.php ファイルに定義されたタスクやストーリーを実行するには、Envoy の run コマンドを使い、実行したいタスクまたはストーリー名を渡します。Envoy はタスクを実行し、リモートサーバーからの出力をリアルタイムで表示します:
php vendor/bin/envoy run deploy
#タスク実行の確認
サーバー上でタスクを実行する前に確認を求めたい場合は、タスク宣言に confirm ディレクティブを追加してください。このオプションは破壊的な操作に特に有用です:
@task('deploy', ['on' => 'web', 'confirm' => true])
cd /home/user/example.com
git pull origin {{ $branch }}
php artisan migrate
@endtask
#通知
#Slack
Envoy は各タスク実行後に Slack へ通知を送信できます。@slack ディレクティブは Slack のフック URL とチャンネルまたはユーザー名を受け取ります。Webhook URL は Slack の管理画面で「Incoming WebHooks」インテグレーションを作成して取得できます。
@slackディレクティブに渡す最初の引数には、Webhook URL 全体を指定してください。@slackディレクティブに渡す2番目の引数はチャンネル名(#channel)またはユーザー名(@user)にしてください:
@finished
@slack('webhook-url', '#bots')
@endfinished
デフォルトでは、Envoy の通知は実行されたタスクを説明するメッセージを通知チャンネルに送信します。しかし、@slack ディレクティブに第3引数を渡すことで、このメッセージをカスタムメッセージに上書きできます:
@finished
@slack('webhook-url', '#bots', 'Hello, Slack.')
@endfinished
#Discord
Envoy は各タスク実行後に Discord へ通知を送信できます。@discord ディレクティブは Discord のフック URL とメッセージを受け取ります。Webhook URL はサーバー設定の「Webhook」から作成し、投稿先チャンネルを選択して取得します。Webhook URL 全体を @discord ディレクティブに渡してください:
@finished
@discord('discord-webhook-url')
@endfinished
#Telegram
Envoy は各タスク実行後に Telegram へ通知を送信できます。@telegram ディレクティブは Telegram Bot ID と Chat ID を受け取ります。Bot ID は BotFather で新しいボットを作成して取得します。Chat ID は @username_to_id_bot で取得可能です。Bot ID と Chat ID を @telegram ディレクティブに渡してください:
@finished
@telegram('bot-id','chat-id')
@endfinished
#Microsoft Teams
Envoy は各タスク実行後に Microsoft Teams へ通知を送信できます。@microsoftTeams ディレクティブは Teams Webhook(必須)、メッセージ、テーマカラー(success, info, warning, error)、およびオプションの配列を受け取ります。Teams Webhook は incoming webhook を作成して取得します。Teams API にはタイトル、概要、セクションなどメッセージボックスをカスタマイズする属性が多数あります。詳細は Microsoft Teams ドキュメント を参照してください。Webhook URL 全体を @microsoftTeams ディレクティブに渡してください:
@finished
@microsoftTeams('webhook-url')
@endfinished