コンテンツにスキップ

Laravel Envoy

はじめに

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

並列実行

デフォルトでは、タスクは各サーバーで順番に実行されます。つまり、タスクは最初のサーバーでの実行が完了してから、2番目のサーバーでの実行に進みます。複数のサーバーでタスクを並列に実行する場合は、タスク宣言に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ファイルをrequireする必要がある場合は、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

ストーリー

ストーリーは、一連のタスクを1つの便利な名前にグループ化します。たとえば、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) {
// There were errors in one of the tasks...
}
@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とチャンネル/ユーザー名を受け入れます。Slackコントロールパネルで「Incoming WebHooks」統合を作成することにより、webhook URLを取得できます。

@slack ディレクティブの最初の引数には、Webhook URL 全体を渡す必要があります。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 の Webhook URL とメッセージを受け取ります。Webhook URL は、サーバー設定で「Webhook」を作成し、Webhook が投稿するチャンネルを選択することで取得できます。Webhook URL 全体を @discord ディレクティブに渡す必要があります。

@finished
@discord('discord-webhook-url')
@endfinished

Telegram

Envoy は、各タスクの実行後に Telegram に通知を送信することもサポートしています。@telegram ディレクティブは、Telegram Bot ID と Chat ID を受け取ります。BotFather を使用して新しいボットを作成することで、Bot ID を取得できます。@username_to_id_bot を使用して、有効な Chat ID を取得できます。Bot ID と Chat ID 全体を @telegram ディレクティブに渡す必要があります。

@finished
@telegram('bot-id','chat-id')
@endfinished

Microsoft Teams

Envoy は、各タスクの実行後に Microsoft Teams に通知を送信することもサポートしています。@microsoftTeams ディレクティブは、Teams Webhook(必須)、メッセージ、テーマカラー(success、info、warning、error)、およびオプションの配列を受け取ります。新しい 受信 Webhook を作成することで、Teams Webhook を取得できます。Teams API には、タイトル、概要、セクションなど、メッセージボックスをカスタマイズするための他の多くの属性があります。詳細は、Microsoft Teams のドキュメント を参照してください。Webhook URL 全体を @microsoftTeams ディレクティブに渡す必要があります。

@finished
@microsoftTeams('webhook-url')
@endfinished