Laravel Envoy は、リモート サーバーで実行する一般的なタスクを実行するためのツールです。
Envoy
過小評価されていると思います。私はいつも Envoy が非常に便利だと思っていますが、あまり使われているようには見えません。この記事では、 Envoy
生産性の向上にどのように役立つかを探ります🚀。
Laravel Envoy は Laravel 開発者専用でも Laravel プロジェクトに限定されておらず、誰でも使用できます ❤️。
まず、 Envoy
の 2 つの重要な概念について説明します。
タスク: サーバーの更新やリポジトリのクローン作成などの特定のアクションを表します。
ストーリー: タスクのコレクションです。
現時点で知っておく必要があるのはこれだけです。すべての機能については、いつでもドキュメントで読むことができます。
この記事では、ほとんどの開発者がアプリケーションをデプロイするときに行う 2 つの作業を自動化します。
Nginx の設定。
SSH キーを生成し、GitHub に追加してプライベート リポジトリにアクセスできるようにします。
はい、わかっています。ほとんどの場合、 Envoy
CI/CD ワークフローに使用されますが、文字通りすべてを実行できます。
まず、ディレクトリを作成しましょう:
mkdir tuto && cd $_
$ take tuto
zsh
を使用している場合は tuto を参照してください。
次のコマンドを実行してEnvoy
をインストールします。
composer require laravel/envoy --dev
composer がインストールされていることを確認してください。
次に、 Envoy.blade.php
というファイルを作成します。はい、 Blade
構文を使用します。とてもクールですよね?
touch Envoy.blade.php
これで完了です。必要なのは 1 つのスクリプトだけです。Laravel や Laravel 関連のプロジェクトに特化する必要はありません。自動化を始めましょう! 😁
新しいサーバーがあり、Nginx をセットアップしたいと考えています。プロセスを分解すると、次のようになります。
まさにそれがEnvoy
で行うことであり、各ステップをTask
、プロセス全体をStory
として考えます。
それでは、先ほど言ったことを物語に翻訳してみましょう。
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory
@servers
ディレクティブは、後でタスクを実行するサーバーを指定するために使用されます。
さて、各タスクの定義に進みます😁
最初のタスクupdate-server
サーバーのパッケージと依存関係が最新であることを確認します。
@task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask
2 番目のタスクinstall-nginx
サーバーに Nginx をインストールします。
@task('install-nginx', ['on' => ['web']]) echo "Installing nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask
デフォルトの Nginx リンクを削除し、 $application_name
変数から取得した名前を使用してアプリケーション用の新しいリンクを作成したことに注意してください。
その変数を使用できるようにするには、それを宣言する必要があるため、 @setup
ディレクティブを含める必要があります。
@setup $application_name = 'your-application-name'; @endsetup
ここで、3 番目のタスクcopy-nginx-stub
に進みます。私の場合は、Laravel アプリケーションをデプロイしているので、ドキュメントで提供されている Nginx 構成ファイルを少し調整して使用します。別のアプリケーションをデプロイする場合は、同じ概念を独自の構成ファイルに適用できます。
先ほど作成したディレクトリで、次のコマンドを実行します。
mkdir stubs; nano stubs/nginx.conf
次に、次のコンテンツをエディターに貼り付けて保存し、終了します。
server { listen 80; listen [::]:80; server_name public_ip; root /var/www/app_name/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
public_ip
とapp_name
現時点ではプレースホルダーであり、変数によって自動的に更新されます。
タスク自体の記述に移りましょう。
@task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask
このタスクは、リモート サーバーではなくローカル マシン上で実行されます。これを指定するには
'on' => 'local'
を使用します。
また、必要な変数を使用して@setup
ディレクティブを更新することを忘れないでください。
@setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup
4 番目で最後のタスクconfigure-nginx
プレースホルダーを更新し、アプリケーションを正しく提供できるようにします。
@task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask
cd
コマンドに注意してください。これは、各タスクが個別に実行されるため、常にリモート サーバーのホーム ディレクトリから開始されるためです。
Nginx のインストール時にすでにシンボリックリンクを作成しているので、今は心配する必要はありません。
これでこのセクションは完了です。スクリプトは次のようになります。
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory @task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask @task('install-nginx', ['on' => ['web']]) echo "Installing nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask @task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask @task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask
Nginx を設定し、アプリケーションを提供する準備ができたので、SSH キーを生成し、GitHub に公開キーを追加して、プライベート リポジトリをプルできるようにする必要があります。
このため、 GitHub REST APIを使用するので、開始する前にトークンを作成する必要があります。
トークンを作成するときは、「admin:public_key」スコープのみを選択してください。
トークンを作成したので、まずは変数を定義しましょう。
@setup $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup
この時点で、このプロセスに含まれる手順について疑問に思われるかもしれません。この手順は 2 つのステップに分けられます。
SSHキーを生成する
公開鍵をGitHubにコピーする
もう一度、このプロセスが私たちの物語になります:
@story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory
最初のタスクgenerate-ssh-keys
、次の 1 つのコマンドを実行するだけで実行できます。
@task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask
SSH キーを生成したら、GitHub API を使用して公開キーを GitHub に追加できます。これは、1 つのリクエストで実行できます。
@task('add-ssh-keys-to-github', ['on' => ['web']]) echo "Adding ssh keys to github..." key=$(cat {{ $ssh_key }}.pub) curl --request POST \ --url https://api.github.com/user/keys \ --header 'Accept: application/vnd.github+json' \ --header 'Authorization: Bearer {{ $github_api_key }}' \ --header 'Content-Type: application/json' \ --header 'X-GitHub-Api-Version: 2022-11-28' \ --data '{ "title": "[Envoy] Public key", "key": "'"$key"'" }' @endtask
これで完了です。GitHub 開発者設定にアクセスすると、新しく作成されたキーが表示されます。
2 つのセクションを組み合わせると、最終的なスクリプトは次のようになります。
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory @story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory @task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask @task('install-nginx', ['on' => ['web']]) echo "Installing Nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask @task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask @task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask @task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask @task('add-ssh-keys-to-github', ['on' => ['web']]) echo "Adding ssh keys to github..." key=$(cat {{ $ssh_key }}.pub) curl --request POST \ --url https://api.github.com/user/keys \ --header 'Accept: application/vnd.github+json' \ --header 'Authorization: Bearer {{ $github_api_key }}' \ --header 'Content-Type: application/json' \ --header 'X-GitHub-Api-Version: 2022-11-28' \ --data '{ "title": "creating from script", "key": "'"$key"'" }' @endtask
Envoy
を使用して一般的なタスクを自動化する方法を学びました。これは、ここで説明した機能よりもさらに多くの機能を備えた強力なツールです。アプリケーションのデプロイだけに限定しないでください。Envoy Envoy
、文字通り思いつくあらゆるターミナル コマンドを自動化できます。
次回、同じコマンドを繰り返し実行していることに気付いたときは、ぜひ使用を検討してください。CI/CD よりもはるかに多くの機能があることをお約束します 😛😛