Развёртывание Laravel приложения с GitHub Actions

Источник: «Automate your Laravel app deployment with Github Actions»
В этой статье я подробно расскажу о том, как вы можете автоматизировать развёртывание Laravel приложения на VPS, разумеется, бесплатно.

Предпосылки

Я состою в небольшой команде, работающей над Laravel проектом, развёрнутым на VPS. Каждый из членов нашей команды работает над определённой задачей, и когда она готова к продакшену, всегда требуется, чтобы получил доступ к серверу для развёртывания каждого изменения, отправляемого в наш GitHub репозиторий.

Это стало часто повторяющейся и неприятной задачей для всех нас, м требовалось решение в рамках нашего масштаба и бюджета. Поэтому мы обратились к могущественным GitHub Actions для автоматизации наших рабочих процессов.

Давайте погрузимся в упрощённую версию нашего руководства по настройке рабочего процесса.

Предположения

В это руководстве я предполагаю, что выполнены следующие моменты.

  1. У вас есть настроенный Linux сервер, на котором можно запускать Laravel приложения, и на нём установлен Git.
  2. У вас есть репозиторий Laravel приложения на Github. Если у вас его нет, то для вас не будет большой проблемой его создать.

Как это работает

В типичном рабочем процессе, разработчик создаст новую ветку для данной задачи и сделает Pull Request в ветку main/master или самостоятельно внесёт изменения в main/master (не рекомендуется) и сделает Push.

Оба, pull request и push — это события в данной ветке, на которые мы можем подписаться с помощью GitHub Actions. Поэтому мы можем определить набор инструкций, которые должны выполняться каждый раз, когда данные события происходят в нашем репозитории. Эти инструкции могут запускать наши тесты Tests, сборку Builds и развёртывание Deployments.

Создание сценария развёртывания Laravel приложения

Первое, что мы сделаем, это создадим сценарий развёртывания содержащий все необходимые команды для развёртывания и запуска нашего приложения.

В корневом каталоге приложения создадим папку .scripts.

Внутри папки .scripts создаём файл deploy.sh со следующим содержимым:

#!/bin/bash
set -e

echo "Deployment started ..."

# Войти в режим обслуживания или вернуть true
# если уже в режиме обслуживания
(php artisan down) || true

# Загрузить последнюю версию приложения
git pull origin production

# Установить зависимости Composer
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader

# Очистить старый кэш
php artisan clear-compiled

# Пересоздать кэш
php artisan optimize

# Скомпилировать ресурсы
npm run prod

# Запустить миграцию базы данных
php artisan migrate --force

# Выход из режима обслуживания
php artisan up

echo "Deployment finished!"

Прочтите комментарии сценария, чтобы узнать, что мы делаем в каждой строке.

Создание workflow

Рабочий процесс (workflow) GitHub Action — это набор инструкций, состоящий из различных заданий и шагов, которые могут быть запущены при возникновении событий, упомянутых выше.

Рабочие процессы репозитория хранятся внутри .github/workflows в корневом каталоге ваших приложений.

Создадим файл deploy.yaml внутри каталога .github/workflows со следующим содержимым:

name: Deploy

# Trigger the workflow on push and
# pull request events on the production branch
on:
push:
branches:
- production
pull_request:
branches:
- production

# Authenticate to the the server via ssh
# and run our deployment script
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: $
username: $
port: $
key: $
script: "cd /var/www/html && ./.scripts/deploy.sh"

Фиксируем созданный файл в репозитории

Теперь, когда мы создали все необходимые для нашей автоматизации файлы зафиксируем их с помощью следующих команд.

git add deploy.sh deploy.yml
git commit -m "Deployment automation"

Создаём ветку развёртывания и отправляем на GitHub

Если вы заметили, что в наших файлах deploy.sh и deploy.yaml мы ссылаемся на ветку production. Мы будем использовать эту ветвь для добавления коммитов готовых к продакшену, с помощью push или pull request.

Создаём эту ветку для своего репозитория с помощью следующих команд и пушим на GitHub:

git checkout -b production
git push -u origin production

Настраиваем ssh ключ

Пришло время настроить соединение между нашим сервером и сервером Github. Для этого необходимо сгенерировать новую пару ssh ключей на сервере. Запустите эту команду на своём сервере для генерации ssh ключа:

ssh-keygen -t rsa -b 4096 -C "email@example.com"

Когда будет предложено ввести имя файла и парольную фразу, просто нажмите Enter и примите значение по умолчанию.

Будет создано два ssh ключа, публичный и приватный, в вашем домашнем каталоге .ssh/.

Теперь добавьте свой только что сгенерированный закрытый ключ в ssh-agent с помощью следующих команд:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

И давайте добавим наш публичный ключ в файл authorized_keys на сервере с помощью следующей команды:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Копирование ssh ключей на GitHub

Наша вышеуказанная установка позволит:

1. GitHub Actions аутентифицироваться на сервере и запускать сценарий deploy.sh

Чтобы это работало, мы должны сообщить GitHub, как аутентифицироваться на нашем сервере.

Поскольку мы подготовили наш ssh ключ ранее, он будет предоставлен Github вместе с сервером HOST, ssh PORT, ssh приватный KEY и USERNAME сервера.

Для этого перейдите в свою учётную запись GitHub в браузере и откройте своё репозиторий.

Кликните на Settings в меню вашего репозиторию (Меню расположено под именем репозитория, Settings последний пункт).

В боковом меню открывшейся страницы выберите пункт Secrets and variables, в появившемся меню выберите пункт Actions.

На открывшейся странице во вкладке Secrets нажмите кнопку New repository secret один за другим, нажимая эту кнопку, следующие секреты:

Как добавить Secret в репозиторий GitHub

HOST

Секрет HOST — это IP-адрес вашего сервера указанный в ключевом слове HOST в поле Name и IP-адрес вашего сервера в поле Secret.

PORT

Секрет PORT — это ваш ssh-порт. Введите PORT в поле Name и номер порта сервера (по умолчанию 22) в поле Secret.

SSHKEY

Секрет SSHKEY — приватный ключ ssh, который мы сгенерировали на сервере. Обычно никто не делиться своими закрытыми ключами с кем-либо, но, поскольку мы занимаемся автоматизацией, это необходимо.

В поле Name введите SSHKEY.

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

cat ~/.ssh/id_rsa

Этот выведет содержимое приватного ключа в терминал, скопируйте его и вставьте в поле Secret.

USERNAME

Последним секретом будет USERNAME, имя пользователя с которым вы хотите проходить аутентификацию на вашем сервере.

Чтобы получить его, вы можете запустить whoami на своём сервере и получить имя пользователя. Затем введите USERNAME в поле Name и в поле Secret введите имя пользователя на сервере.

Когда вы закончите, на странице Actions secrets and variables у вас будет список из четырёх секретов HOST, PORT, SSHKEY и USERNAME.

2. Аутентифицироваться с вашего сервера на GitHub для получения последних коммитов из репозитория.

Чтобы GitHub разрешил доступ с нашего сервера, мы должны предоставить GitHub открытый ssh ключ, который ранее сгенерировали.

Если у нас есть несколько репозиториев, мы можем предоставить открытый ключ на уровне учётной записи. Но если это всего лишь один репозиторий мы можем предоставить его в репозитории и разрешить доступ только к одному репозиторию в нашей учётной записи.

Чтобы сделать это, снова кликаем на пункт меню Settings и на открывшейся страницы, в боковом меню выбираем пункт Deploy keys. На открывшейся странице нажимаем кнопку Add Deploy keys. В поле Title вводим название сервера, например PROD_SERVER. В поле Key вводим содержимое публичного ключа.

Для получения содержимого публичного ключа перейдите на сервер и скопируйте выведенное в терминале содержимое ключа. Содержимое ключа выводится командой:

cat ~/.ssh/id_rsa.pub

Не устанавливайте флажок, разрешения доступа для записи Allow write access, просто введите ключ и нажмите на кнопку Add key.

Последнее, что нужно сделать, это изменить remote origin на нашем сервере, чтобы использовать SSH, вместо HTTPS, и получить на сервере новые коммиты.

Для этого перейдите в свой репозиторий GitHub, кликните кнопку Code и скопируйте ссылку во вкладке ssh.

Кнопка Code репозитория GitHub

Затем на вашем сервере перейдите в каталог вашего развёрнутого приложения, чаще всего это внутри /var/html/www и выполните следующую команду:

git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
git fetch

Замените URL-адрес на тот, который вы скопировали в своём репозитории.

Дайте разрешение на выполнение сценария deploy.sh:

sudo chmod +x ./REPOSITORY/.scripts/deploy.sh

Вот и всё, вы автоматизировали развёртывание своего Laravel приложения.

Создайте тестовый коммит и отправьте его в ветку production, чтобы увидеть, как происходит волшебство.

Вы можете повеселиться расширив workflow добавив тестирование, сборку stage окружения и т.д.

Дополнительные материалы

Предыдущая Статья

Клонирование readonly свойств в PHP 8.3

Следующая Статья

Laravel 10: Пример CRUD с Tailwind CSS