Laravel Envoy - это инструмент для выполнения общих задач, которые вы выполняете на своих удаленных серверах.
Я считаю, что Envoy
его недооценивают, я не вижу, чтобы его использовали очень часто, хотя я всегда находил его очень полезным. В этой статье мы рассмотрим, как Envoy
может помочь повысить вашу производительность🚀.
Laravel Envoy не является эксклюзивным для разработчиков Laravel и не ограничивается проектами Laravel, любой может использовать его ❤️.
Во-первых, давайте обсудим два ключевых понятия в :
- Tasks: which represents a specific action like updating the server or cloning a repository.
- Stories: which is a collection of Tasks.
Это все, что вам нужно знать на данный момент, вы всегда можете прочитать обо всех функциях в Envoy
документации.
Что мы автоматизируем?
В этой статье мы автоматизируем 2 вещи, которые большинство разработчиков делают при развертывании своего приложения:
- Configuring Nginx.
- Generating SSH keys and adding them to GitHub to be able to access private repositories.
Да, я знаю, в большинстве случаев Envoy
используется для рабочих процессов CI/CD, но он может делать ВСЕ, буквально.
Envoy Setup
Сначала давайте создадим каталог
$ take tuto
if you are usingzsh
.
InstallEnvoy
, выполнив следующую команду:
composer require laravel/envoy --dev
Убедитесь, что у вас установлен composer.
Теперь создайте файл с именем Envoy.blade.php
. Да, мы будем использовать синтаксисBlade
, супер круто, верно?
Ну вот! Все, что вам нужно, это один сценарий. Это не обязательно должно быть связано с Laravel или каким-либо проектом, связанным с Laravel. Приступим к автоматизации! 😁
Настройка Nginx У нас есть совершенно новый сервер, и мы хотим настроить Nginx
. Если мы разобьем процесс, это будет похоже на:
- Update the server
- Install Nginx
- Настройка Nginx У нас есть совершенно новый сервер, и мы хотим настроить Nginx
Это именно то, что мы будем делать с Envoy
, думайте о каждом шаге как о , а весь процесс как Story
о Task
.
Итак, давайте переведем то, что мы только что сказали, в историю:
@servers(['web' => '[email protected]', 'local' => '127.0.0.1'])
@story('setup-nginx')
update-server
install-nginx
copy-nginx-stub
configure-nginx
@endstory
Директива
@servers
используется для указания серверов, на которых мы будем выполнять наши задачи в дальнейшем.
Теперь мы можем приступить к определению каждой задачи 😁
Наша первая задача обеспечит актуальность пакетов и зависимостей сервера:Вторая задача install-nginx
update-server
установит Nginx на наш сервер:
@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
Обратите внимание, что мы удалили ссылку 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
необходимыми переменными:Четвертая и последняя задача configure-nginx
обновит заполнители, чтобы мы могли правильно обслуживать приложение:
@setup
$application_name = 'your-application-name';
$production_port = 22;
$production_host = '[email protected]';
@endsetup
@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
Конфигурация ключа SSH Теперь
, когда мы настроили 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
На этом этапе вам может быть интересно узнать о шагах, связанных с этим процессом. Что ж, мы можем разбить его на два этапа:И снова этот процесс будет нашей историей:Первая задача generate-ssh-keys
, можно выполнить, выполнив одну команду:
- Generate SSH keys
- Copy the public key to Github
@story('setup-ssh-keys')
generate-ssh-keys
add-ssh-keys-to-github
@endstory
@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 😛😛