Laravel Envoy — это инструмент для выполнения типичных задач, которые вы выполняете на удаленных серверах.
Я считаю, что Envoy
недооценен; Я не вижу, чтобы его использовали очень часто, хотя я всегда находил его очень полезным. В этой статье мы рассмотрим, как Envoy
может помочь повысить вашу продуктивность🚀.
Laravel Envoy не предназначен исключительно для разработчиков Laravel и не ограничен только проектами Laravel, его может использовать каждый ❤️.
Во-первых, давайте обсудим две ключевые концепции Envoy
:
Задачи : представляют собой конкретное действие, например обновление сервера или клонирование репозитория.
Истории : представляет собой набор задач.
Это все, что вам нужно знать на данный момент; Обо всех функциях вы всегда можете прочитать в документации .
В этой статье мы автоматизируем две вещи, которые большинство разработчиков делают при развертывании своих приложений:
Настройка Нгинкса.
Генерация ключей SSH и добавление их в GitHub для доступа к частным репозиториям.
Да, я знаю, большую часть времени Envoy
используется для рабочих процессов CI/CD, но он может буквально ВСЕ .
Сначала создадим каталог:
mkdir tuto && cd $_
$ take tuto
, если вы используетеzsh
.
Установите Envoy
, выполнив следующую команду:
composer require laravel/envoy --dev
Убедитесь, что у вас установлен композитор.
Теперь создайте файл Envoy.blade.php
. Да, мы будем использовать синтаксис Blade
, очень круто, правда?
touch Envoy.blade.php
Вот и все! Все, что вам нужно, это один сценарий. Это не обязательно должно быть связано с 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
Вторая задача 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
Теперь мы можем перейти к третьей задаче 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
Четвертая и последняя задача 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
На этом этапе вам может быть интересно узнать, какие шаги входят в этот процесс. Ну, мы можем разбить его на два этапа:
Генерация SSH-ключей
Скопируйте открытый ключ на GitHub.
Еще раз об этом процессе и будет наша история:
@story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory
Первую задачу, generate-ssh-keys
, можно выполнить с помощью одной команды:
@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. Это можно сделать одним запросом:
@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, вы должны увидеть только что созданный ключ.
Объединив эти два раздела, ваш окончательный сценарий должен выглядеть следующим образом:
@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
может автоматизировать ЛЮБУЮ команду терминала, буквально всё, что приходит в голову.
В следующий раз, когда вы обнаружите, что повторяете одни и те же команды, подумайте об их использовании, я обещаю вам, что он делает гораздо больше, чем CI/CD 😛😛