-
Notifications
You must be signed in to change notification settings - Fork 58
Версионирование и деплой
Код в репозитрии хранится в ДВУХ ветках
-
master
- здесь "хранятся" новые фичи и некритичные правки. -
production
- содержимое этой ветки выводится на "основном" сервере.
Ведется с примененим ревизий и ревью кода:
Разработчик, получив задачу:
- обновляет репозиторий
- создает от ветки мастер новую ветку с номером задачи и/или с кратким описанием задачи
- пишет код, тестирует его, создает ревизию (Pull/Merge Request etc)
- исправляет код (если требуется) после ревью
- вливает код в мастер ветку, после того как ревизия принята.
Часто бывают ситуации, когда на боевом окружении обнаруживаются неполадки, требующие незамедлительного исправления, в этом случае процесс работы аналогичен описанному выше с той разницей, что ветка для разработки создается от production-ветки, а затем вливается и в нее и в master-ветку.
После того как в мастер-ветку добавлена одна или несколько задач, нужно убедиться, что все работает как и ожидается, ничего не "пропало" из кодовой базы. Не произошло никаких регрессий с предыдущими правками/доработками.
Если все ок, то начинаем готовить production ветку к релизу. На основном сервере необходимо проверить наличие несохраненных правок. Например была добавлена новая страница, новый пункт меню и тд. Для Битрикс это означает изменение файлов. Чтобы не потерять эти изменения нужно:
- зайти на основной сервер.
- проверить - есть ли изменения
git status
- если есть - сделать коммит
git add .
git commit -m 'Production changes'
git push origin production
- у себя получить эти изменения в ветку production:
git checkout production
git pull origin production
- узнать хэш последнего production-коммита (git log например, либо посмотреть в веб интерфейсе, либо на предыдущих шагах), например
164d1f8e335da47f724
- Выполнить команду cherry-pick, чтобы применить этот коммит к master-ветке (cherry-pick позволит "не засорять историю репозитория малоинформативными merge-коммитами"):
git checkout master
-
git pull origin master
на всякий случай git cherry-pick 164d1f8e335da47f724
- Затем нужно убедиться что эти изменения ничего не ломают в мастер-ветке и, если требуется, исправить все неполадки
- Далее производится мерж Мастер-ветки в Продакшн-ветку.
git checkout production
git merge master
Таким образом master ветка получает свежие изменения с "боевого" сайта (благодаря этому получаем возможность более раннего обнаружения потенциальных конфликтов и багов при разработке), а production - все актуальные изменения, готовые к переносу на "боевое" окружение.
В простейших случаях для релиза достаточно на боевом окружении выполнить команду git pull
.
Но при использовании composer
, миграций
и при сборке фронтенда с помощью nodejs
-утилит (а без всего этого нынче никак, либо очень грустно и непродуктивно), сайт в процесса обновления может потерять свою работоспособность. А выполнение вручную таких операций как composer install
, npm run build
и тд повышает вероятность каких либо ошибок в процессе релиза, к тому же все это не самые быстрые операции.
Два очевидных выхода из ситуации:
- самописный скрипт для обновления данных на сайте например такой
- готовый инструмент для деплоя: Capistrano, Vlad, SaltStack, Rocketeer, Deployer (тысячи их)
В нашем случае используется Deployer.
Успешно применяется на части наших относительно крупных проектов, начиная с 3 версии. (Сейчас уже 6)
Работает все предельно просто:
А при желании и необходимости все можно усложнить, добавив хостам "роли", настроив параллельное выполнение задач, расширив функциональность дополнительными задачами и "рецептами". Подробности в документации утилиты.
В файле hosts.yml (раньше был servers.yml
) указываются все возможные "хосты", на которые планируется загружать релизы.
testhost.com:
port: 22
user: testhost_ssh_user
identityFile: ~/.ssh/id_rsa
deploy_path: /home/testhost/project_releases
branch: master
restart_cmd: "service apache2 restart"
prodhost.com:
port: 22
user: bitrix
identityFile: ~/.ssh/id_rsa
deploy_path: /home/bitrix/project_releases
branch: production
restart_cmd: "sudo /bin/systemctl restart httpd.service && sudo /bin/systemctl restart nginx.service"
В файле deploy.php
описывается сценарий деплоя и всякие настройки.
Соответственно, чтобы загрузить изменения на "тестовый" testhost.com
, нужно выполнить команду:
dep deploy testhost.com
Тогда содержимое ветки мастер (ветка указывается в hosts.yml) будет загружено в качестве нового релиза на этот хост.
Если выполнить команду
dep deploy prodhost.com
То релиз загрузится на основной сайт, соответсвенно данные возьмуться из ветки production
В процессе выполнены различные доп. действия:
- создание файловой структуры
- установка зависимостей
- применение миграций
- сброс кеша
- перезагрузка веб-сервера
- смена релиза
Если на каком-то шаге случится ошибка, то данный "релиз" не применится и соответственно это не повлияет на сайт.
.
├── current -> releases/8
├── releases
│ ├── 4
│ ├── 5
│ ├── 6
│ ├── 7
│ └── 8
└── shared
├── bitrix
└── upload
По адресу <deployment_path/current> находится ссылка на последний релиз. Релиз можно "откатить" командой
$ dep deploy rollback
✔ Executing task rollback
В примере выше это будет означать что ссылка current
станет уаказывать на релиз №7, а неудачный релиз №8 будет удален:
.
├── current -> releases/7
├── releases
│ ├── 4
│ ├── 5
│ ├── 6
│ └── 7
└── shared
├── bitrix
└── upload
В директории shared
должны лежать "общие" для всех релизов файлы и папки. В нашем случае это директории bitrix
и upload
. Команда 'deploy:shared'
для каждого релиза содает симлинки на эти директории.
После успешного первого релиза нужно перенести в shared необходимые директории. И создать симлинк для директории веб-сервера.
На сервере это обычно директория /home/username/public_html/ Поэтому для работы с релизами нужна такая ссылка:
/home/testhost/public_html -> /home/testhos/project_releases/current/sites/s1
Для серверов на базе Bitrix VM это /home/bitrix/www/ Симлинк:
/home/bitrix/www -> /home/bitrix/project_releases/current/sites/s1
Так как веб сервер не сразу замечает "переключение" симлинка при новом релизе, то необходима его перезагрузка, за нее отвечает задача
deploy:restart
для каждого хоста нужно указать свою последовательность команд для этого действия в файле hosts.yml
Таски
check:uncommited
иcheck:unpushed
как следует из их названия проверяют директорию предыдущего релиза на наличие незакомиченных и незапушенных изменений и прерывают деплой, если такие вещи есть в релизе. Как разбираться с такими ситуациями написано в самом начале этой заметки
Проверить хост на наличие несохраненных изменений можно командой check
:
$ dep check prodhost.com
Эта проверка автоматически срабатывает при каждом деплое (команда dep deploy hostname
). Чтобы пропустить проверку к команде нужно добавить флаг --skip-git-check
.
$ dep deploy production --skip-git-check