> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Envoy

> Laravel Envoy を使ってリモートサーバー上のデプロイタスクやArtisanコマンドをBlade構文で定義・実行する方法を解説します。

## はじめに

[Laravel Envoy](https://github.com/laravel/envoy) は、リモートサーバー上でよく使うタスクを実行するためのツールです。[Blade](/jp/blade) と同じ構文を使って、デプロイやArtisanコマンドの実行などのタスクを簡単に定義できます。

<Info>
  Envoyは現在、macOSとLinuxのみをサポートしています。Windowsで使う場合は[WSL2](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)経由での利用が必要です。
</Info>

## インストール

Composerパッケージマネージャーを使って、プロジェクトにEnvoyをインストールします。

```shell theme={null}
composer require laravel/envoy --dev
```

インストール後、`vendor/bin`ディレクトリにEnvoyの実行ファイルが利用可能になります。

```shell theme={null}
php vendor/bin/envoy
```

## タスクの作成

### タスクの定義

タスクはEnvoyの基本的な構成要素です。タスクは、タスク実行時にリモートサーバー上で実行すべきシェルコマンドを定義します。たとえば、すべてのキューワーカーサーバーで `php artisan queue:restart` コマンドを実行するタスクを定義できます。

Envoyタスクはすべて、アプリケーションのルートにある `Envoy.blade.php` ファイルに定義します。

```blade theme={null}
@servers(['web' => ['user@192.168.1.1'], 'workers' => ['user@192.168.1.2']])

@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` に指定することで、スクリプトをローカルコンピューター上で強制的に実行できます。

```blade theme={null}
@servers(['localhost' => '127.0.0.1'])
```

#### Envoyタスクのインポート

`@import` ディレクティブを使うと、他のEnvoyファイルをインポートして、そのストーリーやタスクを自分のファイルに追加できます。インポート後は、自身のEnvoyファイルで定義したのと同じようにタスクを実行できます。

```blade theme={null}
@import('vendor/package/Envoy.blade.php')
```

### 複数サーバー

Envoyでは、1つのタスクを複数のサーバーで簡単に実行できます。まず `@servers` 宣言に追加のサーバーを登録し、各サーバーに一意の名前を割り当てます。サーバーを追加したら、タスクの `on` 配列に各サーバーを列挙します。

```blade theme={null}
@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
```

#### 並列実行

デフォルトでは、タスクは各サーバーで直列に実行されます。つまり、あるタスクが1台目のサーバーで完了してから、2台目のサーバーでの実行に進みます。複数サーバーでタスクを並列実行したい場合は、タスク宣言に `parallel` オプションを追加します。

```blade theme={null}
@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 theme={null}
@setup
    $now = new DateTime;
@endsetup
```

タスク実行前に他のPHPファイルを読み込む必要がある場合は、`Envoy.blade.php` ファイルの先頭で `@include` ディレクティブを使います。

```blade theme={null}
@include('vendor/autoload.php')

@task('restart-queues')
    # ...
@endtask
```

### 変数

Envoyタスクを呼び出す際に、コマンドラインで引数を指定してタスクに渡すことができます。

```shell theme={null}
php vendor/bin/envoy run deploy --branch=master
```

タスク内では、Bladeの「echo」構文でオプションにアクセスできます。Bladeの `if` 文やループも定義可能です。たとえば `git pull` コマンドを実行する前に `$branch` 変数の存在を確認する場合は次のようにします。

```blade theme={null}
@servers(['web' => ['user@192.168.1.1']])

@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` タスクをまとめて実行できます。

```blade theme={null}
@servers(['web' => ['user@192.168.1.1']])

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

ストーリーを記述したら、タスクと同じ方法で呼び出せます。

```shell theme={null}
php vendor/bin/envoy run deploy
```

### 完了フック

タスクやストーリーの実行時には、複数のフックが実行されます。Envoyがサポートするフックの種類は `@before`、`@after`、`@error`、`@success`、`@finished` です。これらのフック内のコードはすべてPHPとして解釈され、タスクが操作するリモートサーバーではなく、**ローカルで**実行されます。

各フックはいくつでも定義でき、Envoyスクリプトに記述された順序で実行されます。

```blade theme={null}
@before
    if ($task === 'deploy') {
        // ...
    }
@endbefore

@after
    if ($task === 'deploy') {
        // ...
    }
@endafter

@error
    if ($task === 'deploy') {
        // ...
    }
@enderror

@success
    // ...
@endsuccess

@finished
    if ($exitCode > 0) {
        // いずれかのタスクでエラーが発生した...
    }
@endfinished
```

`@finished` フックは、実行が完了したタスクのステータスコードを受け取ります。ステータスコードは `null` または `0` 以上の整数です。

## タスクの実行

アプリケーションの `Envoy.blade.php` ファイルに定義したタスクやストーリーを実行するには、Envoyの `run` コマンドを実行し、実行したいタスクまたはストーリーの名前を渡します。Envoyはタスクを実行し、実行中にリモートサーバーからの出力を表示します。

```shell theme={null}
php vendor/bin/envoy run deploy
```

### タスク実行の確認

サーバー上で特定のタスクを実行する前に確認を求めたい場合は、タスク宣言に `confirm` ディレクティブを追加します。この機能は破壊的な操作を実行する場合に特に便利です。

```blade theme={null}
@task('deploy', ['on' => 'web', 'confirm' => true])
    cd /home/user/example.com
    git pull origin {{ $branch }}
    php artisan migrate
@endtask
```

## 通知

### Slack

Envoyは、各タスク実行後に[Slack](https://slack.com)へ通知を送信できます。`@slack` ディレクティブは、SlackのWebhook URLとチャンネル名（またはユーザー名）を受け取ります。Webhook URLは、Slackのコントロールパネルで「Incoming WebHooks」インテグレーションを作成することで取得できます。

`@slack` ディレクティブの第1引数にはWebhook URL全体を渡します。第2引数には、チャンネル名（`#channel`）またはユーザー名（`@user`）を指定します。

```blade theme={null}
@finished
    @slack('webhook-url', '#bots')
@endfinished
```

デフォルトでは、実行されたタスクを説明するメッセージが通知チャンネルに送信されます。`@slack` ディレクティブに第3引数を渡すことで、独自のメッセージに上書きできます。

```blade theme={null}
@finished
    @slack('webhook-url', '#bots', 'Hello, Slack.')
@endfinished
```

### Discord

Envoyは、各タスク実行後に[Discord](https://discord.com)へ通知を送信することもサポートしています。`@discord` ディレクティブはDiscordのWebhook URLとメッセージを受け取ります。Webhook URLは、サーバー設定内で「Webhook」を作成し、投稿先チャンネルを選択することで取得できます。

```blade theme={null}
@finished
    @discord('discord-webhook-url')
@endfinished
```

### Telegram

Envoyは、各タスク実行後に[Telegram](https://telegram.org)へ通知を送信することもサポートしています。`@telegram` ディレクティブは、Telegram Bot IDとChat IDを受け取ります。Bot IDは[BotFather](https://t.me/botfather)で新しいボットを作成することで取得できます。Chat IDは[@username\_to\_id\_bot](https://t.me/username_to_id_bot)を使って取得できます。

```blade theme={null}
@finished
    @telegram('bot-id','chat-id')
@endfinished
```

### Microsoft Teams

Envoyは、各タスク実行後に[Microsoft Teams](https://www.microsoft.com/microsoft-teams)へ通知を送信することもサポートしています。`@teams` ディレクティブは、Teamsのwebhook（必須）、メッセージ、テーマカラー（success, info, warning, error）、そしてオプションの設定配列を受け取ります。Teamsのwebhookは、[Incoming Webhook](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook)を作成することで取得できます。Teams APIには他にも多くの設定項目があり、独自のメッセージカードを自由に作成できます。詳細は[Microsoft Teamsのドキュメント](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using)を参照してください。

```blade theme={null}
@finished
    @teams('webhook-url')
@endfinished
```

<Warning>
  Envoyはリモートサーバーへの[SSH](https://ja.wikipedia.org/wiki/Secure_Shell)接続を前提としています。実行環境によっては、鍵認証の設定やサーバーへのアクセス制御を事前に済ませておく必要があります。より高度なデプロイ自動化が必要な場合は、[デプロイメント](/jp/deployment)ガイドや[GitHub Actions](/jp/advanced/github-actions-pinning)との組み合わせも検討してください。
</Warning>
