Дата публикации: 15.10.2024 в 16:21

Гайд по деплою web-приложений для новичков. Часть 3. Простая автоматизация

Danil ShutskyDanil Shutsky
0 комментария

Привет, коллеги! 👋

Продолжаем цикл статей, посвященных деплою приложений на сервер.

Вот ссылки на другие части статьи:

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

  • bash-скрипт
  • GitHub actions

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

Вкратце напомню, что уже изучили, и как мы деплоим вручную:

  1. Есть приватный GitHub-репозиторий с проектом, в который мы пушим изменения с локального репозитория.

  2. Забираем обновленный код из GitHub-репозитория на сервер.

  3. Выполняем команды по обновлению проекта (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 

Контролируем процесс.

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

Сейчас процесс деплоя приведен к виду:

  1. Пушим изменения с локального репозитория в GitHub-репозиторий

  2. Подключаемся к серверу (по SSH, как настроили во второй статье) и запускаем скрипт easy-deploy.sh

Плюсы:

  • Бесплатно. Всё выполняется без использования платных сервисов
  • Автоматизация. Каждый деплой позволяет сэкономить пару минут (по сравнению с ручным деплоем)

Минусы:

  • Надо подключаться к серверу, чтобы запустить скрипт.
  • В процессе выполнения деплоя, приложение переводится в режим обслуживания, а это значит что пользователи не смогут получить доступ к сайту.
  • Отсутствие обратной связи: непонятно как проходит процесс деплоя, необходимо мониторить ход выполнения скрипта на сервере.

По сравнению к деплоем вручную - намного лучше, давайте посмотрим еще один популярный вариант автоматизации.

Вариант 2. GitHub Actions

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

Итак, у GitHub есть Actions, и можно настроить так, чтобы на событие push в GitHub-репозиторий, GitHub будет запускать необходимые команды на сервере. Что надо сделать:

  1. Создать в локальном репозитории рабочий процесс (workflow) GitHub Actions
  2. Добавить информацию для настройки SSH соединения GitHub-сервер - GitHub secrets
  3. Добавить значения из secrets в файл workflow
  4. Запушить workflow в репозиторий на GitHub
  5. Проверяем работу

Велосипед выдумывать не будем, работаем по документации GitHub.

Создание рабочего процесса (workflow) GitHub Actions

Создаём свой workflow - создаем папку в каталоге .github/workflows, в ней файл deploy.yml.

Или работаем на GitHub в разделе "Actions":

Оформим инструкцию для GitHub.

Определение события для запуска 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.

Ссылки на другие статьи по деплою:

А какой опыт автоматизации деплоя у вас? Возможно, вы используете другие инструменты или у вас есть свои хитрости в настройке процесса? Поделитесь своими мыслями и опытом в комментариях!

ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай