Настроим деплой приложения по “Push” в репозиторий на Битбакете.
Задача такая:
- Кто-то сделал
git push
в веткуmaster
в BitBucket - Свежая версия из ветки
master
автоматически подтянулась на продакшен сервер.
Польза от этой автоматизации очень простая: мы избавляем себя от рутинных действий и упрощаем себе жизнь.
По сути, мы создаём минимальный CI/CD для нашего проекта.
Зачем CI/CD?
В настоящее время процессы CI/CD уже стали нормой для современной разработки, поэтому скажу очень кратко, зачем это нужно.
Continuos Integration, CI — непрерывная интеграция кода. Сюда входит автоматическая обработка кода. Прогон тестов, исправление форматирования в коде, снифферы. Всё что улучшает, подтверждает или опровергает качество кода. Польза — код всегда соответствует минимальным критериям качества, также получаем быструю обратную связь по отвалившимся тестам.
Continous Delivery, CD — непрерывная доставка, то есть деплой. Автоматическая раскатка кода на тестовые, стейджинг и боевые сервера. Польза — не требуется тратить время разработчика на деплой, нет ошибок по невнимательности при деплое.
Так как эти процессы тесно связаны друг с другом, а часто объединяются в общий скрипт, то и в обозначении они стоят рядом: CI/CD.
Хорошо настроенные CI/CD процессы здорово упрощают работу, но на их настройку требуется время. Надеюсь, что статья поможет вам сэкономить время настройки.
Схема работы
Вернёмся к частному случаю CD для BitBucket. Рассмотрим подробнее, что должно происходить.
- Разработчик сделал
git push
в веткуmaster
. - Bitbucket принял Push, обновил “у себя” ветку
master
. - Bitbucket дёрнул вебхук сервиса CI/CD, в нашем случае - CircleCI.
- Сервис CI/CD подключился к серверу нашего приложения по SSH.
- Сервис CI/CD запустил скрипт деплоя на сервере нашего приложения.
- Скрипт деплоя “вытянул” свежую версию приложения с BitBucket через Git.
- Скрипт деплоя установил свежую версию приложения.
CircleCI? Почему не Bitbucket Pipelines?
У Битбакета есть встроенная функциональность, BitBucket Pipelines, но она излишне сложна в изучении. При этом, в ней не работают даже примеры из документации.
Есть куча сторонних утилит, но либо они заброшены, либо не работают, либо очень сложны в установке.
В попытках найти готовое решение, чтобы не пришлось всё писать самому, нашёл сервис “Circle CI”, который позволяет на бесплатном аккаунте настроить команды для CI BitBucket.
Его настройка легче и можно найти больше примеров, а также есть ответы на форуме, из которых можно почерпнуть что-то полезное.
Скрипт деплоя
Первым делом нам нужен тот самый скрипт, который обновит версию приложения.
Скрипт различается от одного приложения к другому, но главное что в нём должно быть, это скачивание новой версии кода и установка этого кода.
Вот пример установочного скрипта для приложения на Laravel. Сам скрипт располагается в папке bin
в корне проекта и хранится в том же репозитории что и код приложения.
./bin/deploy.sh
if [ -f ~/.profile ]; then
. ~/.profile
fi
SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" # get the directory name
SCRIPT_DIR="$(realpath "${SCRIPT_DIR}")" # resolve its full path
# Change to the project directory
cd ${SCRIPT_DIR}/..
# Turn on maintenance mode
php artisan down || true
# Pull the latest changes from the git repository
git pull
# Set executable permissions
chmod +x ./bin/*.sh
# Install/update composer dependecies
composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
# Run database migrations
php artisan migrate --force
# Clear caches
php artisan cache:clear
php artisan optimize:clear
# Install node modules
npm ci
# Build assets using Laravel Mix
npm run production
# Turn off maintenance mode
php artisan up
Добавив такой скрипт и загрузив на сервер, мы можем легко протестировать его. Достаточно зайти на сервер приложения по SSH, перейти в папку проекта и выполнить
./bin/deploy.sh
Убедитесь, что для скрипта установлен флаг “executable”, иначе он не запустится. Установить этот флаг можно командой chmod:
chmod +x ./bin/deploy.sh
Этот скрипт подходит для приложения на Laravel. Для вашего приложения, если у вас другой фреймворк, можете нагуглить подобный скрипт или составить самостоятельно.
Убедившись, что скрипт запускается через SSH и делает всё необходимое, приступаем к настройке автоматизации.
Настройка CircleCI и BitBucket
-
Добавляем репозиторий BitBucket в CircleCI, в панели управления CircleCI.
-
Копируем публичный ключ SSH пользователя с сервера приложения.
cat ~/.ssh/id_rsa.pub
Если ключа нет — создаём.
ssh-keygen -t rsa
-
Добавляем публичный ключ SSH в
authorized_keys
.touch ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
-
Добавляем публичный SSH ключ пользователя в настройки репозитория BitBucket.
-
Копируем приватный ключ SSH пользователя с сервера приложения.
cat ~/.ssh/id_rsa
-
Добавляем SSH ключ в настройки проекта в Circle CI.
Projects -> My Project -> Project Settings -> SSH Keys -> Additional SSH Keys -> Add SSH Key
Вводим имя хоста и приватный ключ SSH.
Конфиг для CircleCI
Для того, чтобы сервис CircleCI знал, что ему делать с нашим резпоиторием, нужно создать для него конфиг.
В конфиге мы опишем все действия, которые будут выполнены в CircleCI при получении вебхука от BitBucket.
Создаём папку .circleci
в корне проекта — внимание — с точкой!
В папке создаём файл config.yml
со следующим содержанием:
.circleci/config.yml
# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1
# Orchestrate or schedule a set of jobs
workflows:
ssh-deploy:
jobs:
- execute-ssh-deploy:
filters:
branches:
only: master
jobs:
execute-ssh-deploy:
docker:
- image: circleci/welcome-config-image:0.2.1
steps:
- run:
# Установить переменные в настройках проекта в интерфейсе CircleCI
command: ssh -o "StrictHostKeyChecking no" ${SSH_DEPLOY_USER}@${SSH_DEPLOY_HOST} './paster/bin/deploy.sh'
name: Deploy master branch to a production server
Добавляем переменные окружения в настройках проекта в CircleCI: SSH_DEPLOY_USER
, SSH_DEPLOY_HOST
.
Указываем в них, под каким пользователем CircleCI подключится по SSH к серверу приложения при запуске деплоя, а также сам сервер.
Не забываем залить конфиг в репозиторий.
Готово! Теперь при каждом пуше в мастер, приложение на сервере само себя обновит.