Laravel Envoy
イントロダクション
Laravel Envoyは、リモートサーバで実行する一般的なタスクを実行するためのツールです。Bladeスタイルの構文を使用して、デプロイ、Artisanコマンドなどのタスクを簡単に設定できます。現在、EnvoyはMacとLinuxオペレーティングシステムのみをサポートしています。しかし、WSL2を使用すればWindowsのサポートも可能です。
インストール
まず、Composerパッケージマネージャを使用して、プロジェクトにEnvoyをインストールします。
1composer require laravel/envoy --dev
Envoyがインストールされると、Envoyバイナリはアプリケーションのvendor/binディレクトリで利用可能になります。
1php vendor/bin/envoy
タスクの記述
タスクの定義
タスクはEnvoyの基本的な構成要素です。タスクは、タスクが呼び出されたときにリモートサーバで実行されるべきシェルコマンドを定義します。例えば、アプリケーションのすべてのキュワーカサーバでphp artisan queue:restartコマンドを実行するタスクを定義することができます。
すべてのEnvoyタスクは、アプリケーションのルートにあるEnvoy.blade.phpファイルで定義する必要があります。以下は、手始めのサンプルです。
2 3@task('restart-queues', ['on' => 'workers'])4 cd /home/user/example.com5 php artisan queue:restart6@endtask
ご覧のとおり、ファイルの先頭で@serversの配列が定義されており、タスク宣言のonオプションを介してこれらのサーバを参照できます。@servers宣言は常に一行で記述してください。@task宣言の中に、タスクが呼び出されたときにサーバで実行すべきシェルコマンドを記述します。
ローカルタスク
サーバのIPアドレスを127.0.0.1として指定することで、スクリプトをローカルコンピュータ上で強制的に実行できます。
1@servers(['localhost' => '127.0.0.1'])
Envoyタスクのインポート
@importディレクティブを使用すると、他のEnvoyファイルをインポートして、そのストーリーやタスクを自分のファイルに追加できます。ファイルがインポートされた後、自分のEnvoyファイルで定義されているかのように、それらに含まれるタスクを実行できます。
1@import('vendor/package/Envoy.blade.php')
複数サーバ
Envoyを使用すると、複数のサーバでタスクを簡単に実行できます。まず、@servers宣言に追加のサーバを追加します。各サーバには一意の名前を割り当てる必要があります。追加のサーバを定義したら、タスクのon配列に各サーバをリストアップできます。
1@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])2 3@task('deploy', ['on' => ['web-1', 'web-2']])4 cd /home/user/example.com5 git pull origin {{ $branch }}6 php artisan migrate --force7@endtask
並列実行
デフォルトでは、タスクは各サーバで直列に実行されます。つまり、最初のサーバでタスクの実行が完了してから、次のサーバで実行に進みます。複数のサーバでタスクを並行して実行したい場合は、タスク宣言にparallelオプションを追加します。
1@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])2 3@task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])4 cd /home/user/example.com5 git pull origin {{ $branch }}6 php artisan migrate --force7@endtask
セットアップ
Envoyタスクを実行する前に、任意のPHPコードを実行する必要がある場合があります。@setupディレクティブを使用して、タスクの前に実行する必要のあるPHPコードのブロックを定義できます。
1@setup2 $now = new DateTime;3@endsetup
タスクが実行される前に他のPHPファイルを読み込む必要がある場合は、Envoy.blade.phpファイルの先頭で@includeディレクティブを使用できます。
1@include('vendor/autoload.php')2 3@task('restart-queues')4 # ...5@endtask
変数
必要に応じて、Envoyを起動する際にコマンドラインで引数を指定することで、Envoyタスクに引数を渡すことができます。
1php vendor/bin/envoy run deploy --branch=master
Bladeの「echo」構文を使用して、タスク内でオプションにアクセスできます。タスク内でBladeのif文やループを定義することもできます。たとえば、git pullコマンドを実行する前に$branch変数が存在するかどうかを確認してみましょう。
2 3@task('deploy', ['on' => 'web']) 4 cd /home/user/example.com 5 6 @if ($branch) 7 git pull origin {{ $branch }} 8 @endif 9 10 php artisan migrate --force11@endtask
ストーリー
ストーリーは、一連のタスクを単一の便利な名前の下にグループ化します。たとえば、deployストーリーは、その定義内にタスク名をリストすることで、update-codeタスクとinstall-dependenciesタスクを実行できます。
2 3@story('deploy') 4 update-code 5 install-dependencies 6@endstory 7 8@task('update-code') 9 cd /home/user/example.com10 git pull origin master11@endtask12 13@task('install-dependencies')14 cd /home/user/example.com15 composer install16@endtask
ストーリーを記述したら、タスクを呼び出すのと同じ方法で呼び出すことができます。
1php vendor/bin/envoy run deploy
フック
タスクとストーリーが実行されると、いくつかのフックが実行されます。Envoyでサポートされているフックタイプは@before、@after、@error、@success、@finishedです。これらのフック内のコードはすべてPHPとして解釈され、タスクがやり取りするリモートサーバではなく、ローカルで実行されます。
これらのフックはそれぞれ、好きなだけ定義できます。Envoyスクリプトに記述されている順序で実行されます。
@before
各タスクの実行前に、Envoyスクリプトに登録されているすべての@beforeフックが実行されます。@beforeフックは、実行されるタスクの名前を受け取ります。
1@before2 if ($task === 'deploy') {3 // ...4 }5@endbefore
@after
各タスクの実行後、Envoyスクリプトに登録されているすべての@afterフックが実行されます。@afterフックは、実行されたタスクの名前を受け取ります。
1@after2 if ($task === 'deploy') {3 // ...4 }5@endafter
@error
すべてのタスクの失敗(終了コードが0より大きい)の後、Envoyスクリプトに登録されているすべての@errorフックが実行されます。@errorフックは、実行されたタスクの名前を受け取ります。
1@error2 if ($task === 'deploy') {3 // ...4 }5@enderror
@success
すべてのタスクがエラーなしで実行された場合、Envoyスクリプトに登録されているすべての@successフックが実行されます。
1@success2 // ...3@endsuccess
@finished
すべてのタスクが実行された後(終了ステータスに関係なく)、すべての@finishedフックが実行されます。@finishedフックは、完了したタスクのステータスコードを受け取ります。これはnullまたは0以上のintegerである可能性があります。
1@finished2 if ($exitCode > 0) {3 // There were errors in one of the tasks...4 }5@endfinished
タスクの実行
アプリケーションのEnvoy.blade.phpファイルで定義されているタスクまたはストーリーを実行するには、Envoyのrunコマンドを実行し、実行したいタスクまたはストーリーの名前を渡します。Envoyはタスクを実行し、タスクの実行中にリモートサーバからの出力を表示します。
1php vendor/bin/envoy run deploy
タスク実行の確認
サーバで特定のタスクを実行する前に確認のプロンプトを表示したい場合は、タスク宣言にconfirmディレクティブを追加する必要があります。このオプションは、破壊的な操作に特に便利です。
1@task('deploy', ['on' => 'web', 'confirm' => true])2 cd /home/user/example.com3 git pull origin {{ $branch }}4 php artisan migrate5@endtask
通知
Slack
Envoyは、各タスクの実行後にSlackへ通知を送信することをサポートしています。@slackディレクティブは、SlackのフックURLとチャンネル/ユーザー名を受け付けます。Slackのコントロールパネルで「Incoming WebHooks」インテグレーションを作成することで、Webhook URLを取得できます。
Webhook URL全体を@slackディレクティブに与える最初の引数として渡してください。@slackディレクティブに与える2番目の引数は、チャンネル名(#channel)またはユーザー名(@user)である必要があります。
1@finished2 @slack('webhook-url', '#bots')3@endfinished
デフォルトでは、Envoy通知は実行されたタスクを説明するメッセージを通知チャンネルに送信します。しかし、@slackディレクティブに3番目の引数を渡すことで、このメッセージを独自のカスタムメッセージで上書きできます。
1@finished2 @slack('webhook-url', '#bots', 'Hello, Slack.')3@endfinished
Discord
Envoyは、各タスクの実行後にDiscordへの通知送信もサポートしています。@discordディレクティブは、DiscordのフックURLとメッセージを受け取ります。Webhook URLは、サーバー設定で「Webhook」を作成し、Webhookが投稿するチャンネルを選択することで取得できます。Webhook URL全体を@discordディレクティブに渡す必要があります。
1@finished2 @discord('discord-webhook-url')3@endfinished
Telegram
Envoyは、各タスクの実行後にTelegramへの通知送信もサポートしています。@telegramディレクティブは、TelegramボットIDとチャットIDを受け取ります。ボットIDは、BotFatherを使用して新しいボットを作成することで取得できます。有効なチャットIDは@username_to_id_botを使用して取得できます。ボットIDとチャットID全体を@telegramディレクティブに渡してください。
1@finished2 @telegram('bot-id','chat-id')3@endfinished
Microsoft Teams
Envoyは、各タスクの実行後にMicrosoft Teamsへの通知送信もサポートしています。@microsoftTeamsディレクティブは、TeamsのWebhook(必須)、メッセージ、テーマカラー(success、info、warning、error)、およびオプションの配列を受け取ります。TeamsのWebhookは、新しい着信Webhookを作成することで取得できます。Teams APIには、タイトル、サマリー、セクションなど、メッセージボックスをカスタマイズするための他の多くの属性があります。詳細については、Microsoft Teamsのドキュメントで確認できます。Webhook URL全体を@microsoftTeamsディレクティブに渡す必要があります。
1@finished2 @microsoftTeams('webhook-url')3@endfinished