跳到內容

Laravel Envoy

簡介

Laravel Envoy 是一個用於執行您在遠端伺服器上執行之常見任務的工具。使用 Blade 風格的語法,您可以輕鬆設定部署、Artisan 命令等任務。目前,Envoy 僅支援 Mac 和 Linux 作業系統。但是,使用 WSL2 可以實現 Windows 支援。

安裝

首先,使用 Composer 套件管理器將 Envoy 安裝到您的專案中

composer require laravel/envoy --dev

安裝 Envoy 後,Envoy 二進位檔將在您應用程式的 vendor/bin 目錄中可用

php vendor/bin/envoy

編寫任務

定義任務

任務是 Envoy 的基本組成部分。任務定義當任務被調用時應在遠端伺服器上執行的 shell 命令。例如,您可能會定義一個任務,在您所有應用程式的佇列工作伺服器上執行 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 宣告應始終放在單行上。在您的 @task 宣告中,您應該放置當任務被調用時應在您的伺服器上執行的 shell 命令。

本機任務

您可以將伺服器的 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-codeinstall-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 或大於或等於 0integer

@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。

您應將整個 webhook URL 作為給定給 @slack 指令的第一個參數傳遞。給定給 @slack 指令的第二個參數應該是通道名稱 (#channel) 或使用者名稱 (@user)

@finished
@slack('webhook-url', '#bots')
@endfinished

預設情況下,Envoy 通知將向通知通道發送一則訊息,描述已執行的任務。但是,您可以透過將第三個參數傳遞給 @slack 指令,使用您自己的自訂訊息覆寫此訊息

@finished
@slack('webhook-url', '#bots', 'Hello, Slack.')
@endfinished

Discord

Envoy 也支援在每次任務執行後傳送通知到 Discord@discord 指令接受一個 Discord webhook URL 和訊息。您可以在伺服器設定中建立一個「Webhook」,並選擇 webhook 應發佈到的頻道,來取得您的 webhook URL。您應該將完整的 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(必填)、一則訊息、主題顏色(成功、資訊、警告、錯誤)和一個選項陣列。您可以通过創建一個新的 接收 Webhook 來取得您的 Teams Webhook。Teams API 有許多其他屬性可以自訂您的訊息框,例如標題、摘要和區段。您可以在 Microsoft Teams 文件中找到更多資訊。您應該將完整的 Webhook URL 傳遞到 @microsoftTeams 指令中。

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