• Время чтения ~4 мин
  • 30.06.2023

Laravel Envoy - это инструмент для выполнения общих задач, которые вы выполняете на своих удаленных серверах.

Я считаю, что Envoy его недооценивают, я не вижу, чтобы его использовали очень часто, хотя я всегда находил его очень полезным. В этой статье мы рассмотрим, как Envoy может помочь повысить вашу производительность🚀.

Laravel Envoy не является эксклюзивным для разработчиков Laravel и не ограничивается проектами Laravel, любой может использовать его ❤️.

Во-первых, давайте обсудим два ключевых понятия в :

  1. Tasks: which represents a specific action like updating the server or cloning a repository.
  2. Stories: which is a collection of Tasks.

Это все, что вам нужно знать на данный момент, вы всегда можете прочитать обо всех функциях в Envoyдокументации.

Что мы автоматизируем?

В этой статье мы автоматизируем 2 вещи, которые большинство разработчиков делают при развертывании своего приложения:

  1. Configuring Nginx.
  2. 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 using zsh.

InstallEnvoy, выполнив следующую команду:

composer require laravel/envoy --dev

Убедитесь, что у вас установлен composer.

Теперь создайте файл с именем Envoy.blade.php. Да, мы будем использовать синтаксисBlade, супер круто, верно?

Ну вот! Все, что вам нужно, это один сценарий. Это не обязательно должно быть связано с Laravel или каким-либо проектом, связанным с Laravel. Приступим к автоматизации! 😁

Настройка Nginx У нас есть совершенно новый сервер, и мы хотим настроить Nginx

. Если мы разобьем процесс, это будет похоже на:

  1. Update the server
  2. Install Nginx
  3. Настройка 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, можно выполнить, выполнив одну команду:

  1. Generate SSH keys
  2. 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 😛😛

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297