Развёртывание Laravel приложения с GitHub Actions
Предпосылки
Я состою в небольшой команде, работающей над Laravel проектом, развёрнутым на VPS. Каждый из членов нашей команды работает над определённой задачей, и когда она готова к продакшену, всегда требуется, чтобы получил доступ к серверу для развёртывания каждого изменения, отправляемого в наш GitHub репозиторий.
Это стало часто повторяющейся и неприятной задачей для всех нас, м требовалось решение в рамках нашего масштаба и бюджета. Поэтому мы обратились к могущественным GitHub Actions для автоматизации наших рабочих процессов.
Давайте погрузимся в упрощённую версию нашего руководства по настройке рабочего процесса.
Предположения
В это руководстве я предполагаю, что выполнены следующие моменты.
- У вас есть настроенный Linux сервер, на котором можно запускать Laravel приложения, и на нём установлен Git.
- У вас есть репозиторий 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
один за другим, нажимая эту кнопку, следующие секреты:
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
.
Затем на вашем сервере перейдите в каталог вашего развёрнутого приложения, чаще всего это внутри /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 окружения и т.д.