Привет, коллеги! ?
Продолжаем цикл статей, посвященных деплою приложений на сервер.
Вот ссылки на другие части статьи:
Сегодня покажу, как можно автоматизировать деплой. Два варианта, которые отлично подойдут новичкам для ускорения деплоя:
bash-скрипт
GitHub actions
Вручную делать деплой каждый раз не комильфо, бывают проекты, которые надо деплоить ежедневно. Поэтому будем учиться, как деплой автоматизировать.
Вкратце напомню, что уже изучили, и как мы деплоим вручную:
Есть приватный GitHub-репозиторий с проектом, в который мы пушим изменения с локального репозитория.
Забираем обновленный код из GitHub-репозитория на сервер.
Выполняем команды по обновлению проекта (composer-зависимости, выполняем миграции, пересобираем ассеты, перезапускаем джобы и так далее).
То есть кучу команд необходимо запустить и на локальном рабочем месте, и на сервере. И это, конечно же, неудобно. Здесь достаточно много ручной работы, это наводит уныние. Да и можно всего одну команду упустить, и деплой будет неудачным!
Давайте автоматизировать это дело!
Что у нас есть на старте
Автоматизировать мы будем деплой проекта на Laravel, репозиторий с демо-версией админки MoonShine - https://github.com/moonshine-software/demo-project.
В этой статье мы автоматизируем деплой проекта, который уже был развернут и настроен. Если вы делаете деплой проекта в первый раз, выполните настройку по этим статьям:
shared-хостинг, VPS.
Вариант 1. bash-скрипт на сервере
Самый простой вариант по автоматизации деплоя. Сделаем обычный bash-скрипт, который будем запускать одной командой на сервере, а он будет делать все за нас.
Назовём скрипт easy-deploy.sh
.
Приступаем к наполнению скрипта командами. Чтобы интерпретатор понял, что это именно bash-скрипт, мы должны написать вот такую конструкцию в начале файла:
#!/bin/bash
Подстелим себе соломку: добавим инструкцию set –e
. Если одна из команд завершится с ошибкой, то скрипт прекратит работу. И дальше пишем команды для деплоя (для Composer и миграций желательно использовать флаги --no-interaction
и --force
соответственно. Они позволяют выполнять команды без необходимости вмешательства пользователя, что важно для автоматизированного процесса деплоя):
#!/bin/bash
set -e
# Переходим в директорию проекта
cd /var/www/moonshinedemo
# Переводим приложение в режим обслуживания
php artisan down
# Обновляем код из GitHub-репозитория
git pull
# Устанавливаем зависимости Composer
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
# Выполняем миграции базы данных
php artisan migrate --force
# Собираем ассеты для production среды
npm run build
# Очищаем все кэши
php artisan optimize:clear
# Кэшируем
php artisan optimize
# Перезапускаем задания в очереди
php artisan queue:restart
# Выводим приложение из режима обслуживания
php artisan up
Сохраняем. Теперь новую версию приложения попробуем забрать при помощи этого скрипта, и он должен выполнить команды, которые мы прописали.
Давайте проверять. Делаем коммит и обновляем проект на сервере. Вот появился у нас скрипт, давайте запустим его:
sh easy-deploy.sh
Контролируем процесс.
Все выполнилось, отлично! Видим, что зависимости обновились, новых миграций не было, кэш очищен и пересоздан, джобы перезапущены, ассеты сбилдились, приложение переведено в режим работы.
Сейчас процесс деплоя приведен к виду:
Пушим изменения с локального репозитория в GitHub-репозиторий
Подключаемся к серверу (по SSH, как настроили во второй статье) и запускаем скрипт
easy-deploy.sh
Плюсы:
Бесплатно. Всё выполняется без использования платных сервисов
Автоматизация. Каждый деплой позволяет сэкономить пару минут (по сравнению с ручным деплоем)
Минусы:
Надо подключаться к серверу, чтобы запустить скрипт.
В процессе выполнения деплоя, приложение переводится в режим обслуживания, а это значит что пользователи не смогут получить доступ к сайту.
Отсутствие обратной связи: непонятно как проходит процесс деплоя, необходимо мониторить ход выполнения скрипта на сервере.
По сравнению к деплоем вручную - намного лучше, давайте посмотрим еще один популярный вариант автоматизации.
Вариант 2. GitHub Actions
GitHub Actions — это инструмент для автоматизации рутинных задач в разработке программного обеспечения. Он позволяет настроить автоматическое тестирование, сборку и деплой приложения. GitHub Actions глубоко интегрирован в экосистему инструментов GitHub.
Итак, у GitHub есть Actions, и можно настроить так, чтобы на событие push в GitHub-репозиторий, GitHub будет запускать необходимые команды на сервере. Что надо сделать:
Создать в локальном репозитории рабочий процесс (workflow) GitHub Actions
Добавить информацию для настройки SSH соединения GitHub-сервер - GitHub secrets
Добавить значения из secrets в файл workflow
Запушить workflow в репозиторий на GitHub
Проверяем работу
Велосипед выдумывать не будем, работаем по документации GitHub.
Создание рабочего процесса (workflow) GitHub Actions
Создаём свой workflow - создаем папку в каталоге .github/workflows
, в ней файл deploy.yml
.
Оформим инструкцию!
Определение события для запуска workflow
on:
push:
branches:
- main
Указываем, что выполняем workflow после события push в ветку main
(указываем нужную).
Для выполнения команд на удаленном сервере через SSH мы используем appleboy/ssh-action@master
(это GitHub Action, созданный пользователем с именем "appleboy". Позволяет подключиться к удалённому серверу через SSH и
выполнять команды на этом сервере).
Что делает эта Action:
Она предоставляет возможность подключиться к удалённому серверу через SSH.
После подключения можно выполнять команды или скрипты на этом сервере.
Определение задач (jobs) рабочего процесса
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- name: SSH Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/moonshinedeploy.ru
php artisan down
git pull
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
php artisan migrate --force
npm run production
php artisan optimize:clear
php artisan optimize
php artisan queue:restart
php artisan up
Файл для работы workflow готов. Обратите внимание на ${{ secrets.SSH_HOST }}
, ${{ secrets.SSH_USERNAME }}
и ${{ secrets.SSH_PRIVATE_KEY }}
. Это переменные для настройки подключению к серверу, которые нам нужно будет создать на GitHub.
Настроим secrets GitHub
Хранить информацию по подключению к серверу в файле, который лежит в репозитории, ненадежно.
Для хранения конфиденциальной информации (такой как пароли, ключи API и т.д.) придуманы secrets - это переменные, которые вы можете использовать в вашем репозитории GitHub. Secrets предоставляют безопасный способ хранения данных (GitHub обещает, что всё храниться в зашифрованном виде), которые нужны для настройки GitHub Actions workflows.
Secrets находятся в настройках репозитория GitHub - "Secrets and Variables", раздел "Actions".
Добавляем информацию для настройки SSH подключения:
SSH_HOST - IP_адрес_вашего_сервера
SSH_USERNAME - имя_пользователя
Переходим к SSH ключам. При настройке SSH-соединения приватный ключ должен храниться на устройстве, с которого вы планируете подключаться к удаленному рабочему месту. А публичный ключ, должен быть скопирован на удаленное рабочее место (к которому мы будем подключаться). Подключаться мы будем с GitHub к серверу. Получается, что мы должны приватный ключ хранить на GitHub, а публичный (.pub
) - на сервере.
Сгенерируем на сервере пару ключей для нового SSH-соединения "GitHub-сервер". При генерации придумайте уникальное название, например, "github actions" (чтобы потом проще было найти):
ssh-keygen -t rsa -C "github actions"
- C "github actions": добавляет комментарий к ключу. Это помогает идентифицировать ключ, особенно если у вас их несколько.
Указываем имя для файла с ключами:
Enter file in which to save the key (/home/localadmin/.ssh/id_rsa): /home/localadmin/.ssh/gitHubSSH
Готово!
Копируем значение приватного ключа в секрет SSH_PRIVATE_KEY
(начиная от —Begin…
до …end ssh private key—
).
Сам файл приватного ключа можно удалить (на всякий случай, чтобы никто не смог подключиться к нашему серверу).
Итак, secrets настроены, файл с workflow у нас готов, нужно отправить его на GitHub. Создаем новый коммит с изменением, пушим на GitHub.
Смотрим, появился ли наш workflow в разделе Actions.
Ждём пока выполнился workflow. Проверяем.
Всё отлично. Но есть недостаток: что происходит в workflow не видим. git push
выполнили и дальше ждем, когда проект обновится на сервере. Как решить? Надо либо заходить в экшены репозитория и мониторить работу в режиме реального времени, либо настраивать уведомления на email.
Настраиваем уведомления на почту. Чекбокс стоит, что получаем уведомления о неудачных workflow, если же хотите получать и об успешном выполнении, то снимаем чекбокс.
Плюсы:
Интеграция с GitHub. GitHub Actions полностью интегрирован с GitHub, что упрощает настройку и управление рабочими процессами прямо из вашего репозитория.
Бесплатно (без ограничений) для открытых репозиториев.
Автоматизация. Каждый деплой позволяет сэкономить пару минут (по сравнению с ручным деплоем)
Минусы:
Ограниченное количество минут GitHub Actions для private-репозиториев на бесплатном тарифе
В процессе выполнения, приложение переводится в режим обслуживания,а значит пользователи не смогут получить доступ к сайту
Отсутствие обратной связи: мониторим ход выполнения workflow или настраиваем уведомления на email
Непростая настройка: новичкам придется попотеть, но как мы убедились это выполнимая задача
Выводы
Автоматизация процесса деплоя является важным шагом в оптимизации рабочего процесса разработки, особенно для проектов, требующих частых обновлений. Оба метода значительно экономят время по сравнению с ручным деплоем и минимизируют человеческие ошибки.
Выбор метода зависит от конкретных потребностей проекта, уровня навыков команды и желаемой степени автоматизации.
Автоматизация деплоя - это важный шаг в направлении более эффективной и надежной разработки программного обеспечения, который может значительно улучшить рабочий процесс команды.
В следующей статье покажу, как автоматизировать деплой Laravel-приложений с использованием Laravel Envoy.
Ссылки на другие части статьи по деплою:
А какой опыт автоматизации деплоя у вас? Возможно, вы используете другие инструменты или у вас есть свои хитрости в настройке процесса? Поделитесь своими мыслями и опытом в комментариях!
Комментарии (17)
rsmike
15.10.2024 14:13и кстати, забыли еще один краеугольный камень лиги велосипедного деплоя - репозиторий на продакшене, разворачивающий свежий комит в себя с помощью post-receive hook
evgenyk
15.10.2024 14:13Минусы:
Надо подключаться к серверу, чтобы запустить скрипт.
Отсутствие обратной связи: непонятно как проходит процесс деплоя, необходимо мониторить ход выполнения скрипта на сервере.
SSH позволяет запускать скрипты на сервере, из комамндной строки на рабочей станции, причем стандартный выход серверного скрипта перенаправляется на рабочую станцию. Т.о. можно написать еще один маленький однострочный скрипт у себя на рабочей станции, запустив который проведем обновление и процесс деплоя будет виден у нас на рабочей станции.
savostin
15.10.2024 14:13Плюс не отдавать ssh ключ и доступ к проду пусть и честному и секьюрному гитхабу, но все ж
evgenyk
15.10.2024 14:13Еще плюс, с моей точки зрения то, что не нужно использовать постороннее решение. Испольование посторонних решений это всегда баланс между экономией времени и головной болью, когда то одно постороннее решение или падает, или меняет версию и перестает работать.
Причем иногда и даже часто построить велосипед занимает меньше времени.
EugKor
15.10.2024 14:13Хорошая статья, спасибо. Есть момент, что лучше вместо
git pull
использовать:git fetch --all
git reset --hard origin/master
Это позволит избежать конфликтов если вы пересоздали ветку master.
smitt14ua
15.10.2024 14:13Лучше через контейнеры и образы, так можно будет быстро развернуть предыдущую версию без revert-ов в репозитории
Cutcode Автор
15.10.2024 14:13А мы пока не про лучше или хуже а рассматриваем все способы, это уже третья часть) идем от мира динозавров к современным решениям, еще будет как минимум 2-3 статьи
AlexFromHabr
15.10.2024 14:13Коллеги, неужели в русском языке нет адекватных слов чтобы передать смысл слов "гайд" и "деплой"? Это просто ужас какой то во что превратился русский язык у IT-шников. Это совсем некруто использовать эти слова. А как IT-шники произносят http и css - это ужас ужасный.
ideldotpro
15.10.2024 14:13Потому что эти слова компактные и точно описывают предмет или действие. Вот в статье еще нашел исконно русские слова:
цикл, сервер, автоматизация, скрипт, комильфо, приватный, проект, репозиторий, команда, миграция, локальный, старт, демо, версия, админка, вариант, интерпретатор, конструкция, флаг, процесс, режим, контроль, кэш, сервис, экономия, минута, популярный и т.д.
А почему к этим словам нет вопросов? Потому что добавили в словарь русского языка? Или просто привыкли?AlexFromHabr
15.10.2024 14:13Кто в здравом уме, который не знает английского языка (знаю что таких мало в IT) поймет что такое деплой? Он скорее поймет слово развертывание системы или установка приложения/программы. К словам, которые Вы указали, нет русских аналогов. Слово Гайд это руководство, деплой - развертывание или установка.
В крайнем случае напишите их в английском написании. Не коверкайте русский язык. Так писать - себя не уважать.
Cutcode Автор
15.10.2024 14:13Понимаю что это не совсем хорошо, но использовать только славянские слова не получается, чтобы ёмко оформлять статьи для разработчиков. Слову "деплой" наиболее соответствует выражение "развёртывание приложения на сервере". Использование такого более длинного выражения наверное расстроит читателей сильнее
AlexFromHabr
15.10.2024 14:13Можно написать просто развертывание или установка, ваш вариант тоже подходит.
Vadiok
15.10.2024 14:13Развертывание и установка - это скорее что-то про начальную подготовку к запуску. Деплой же про доставку изменений кода до пользователя.
rsmike
я просто оставлю это здесь
https://deployer.org/
есть поддержка всех фреймворков и голого php, есть provisioning из коробки, есть официальный github action, тривиален в настройке, опен сорс
примерно представлять как все устроено новичкам, конечно, не повредит, но вместо велосипеда на баш-скриптах лучше взять проверенное решение с базово необходимым функционалом. Если деплой уронит прод, неплохо хотя как минимум иметь возможность его откатить за несколько секунд
censor2005
А у ларавела есть нативный пакет Envoy, позволяет выполнять команды на удаленном сервере
Cutcode Автор
Про Envoy еще расскажу, запланировано.