08.26
Недавно решил для одного из своих текущих проектов таки сделать легкий автоматический деплоймент.
Сам проект написан на Django в песочнице virtualenv, крутится все это на apache + mod_wsgi. Сам проект лежит в приватном репозитории на github.
Изначально было два варианта:
- деплоить используя fabric из локальной машины
- просто делать пуш на гитхаб, он делает пост вызов странички которая дергает скрипт на сервере, который уже все деплоит сам
Первый вариант я както пробовал, все хоршо, только на проекте еще работает человек, который в программировании ничего не шарит и который с горем пополам разобрался как коммитить в гите.
Значит план работы процесса деплоймента такой:
- После завершения изменений в коде мы делаем пуш на удаленный репозиторий( который у нас на гитхабе).
- Гитхаб после пуша делает пост вызов с данными заданной странички на нашем сервере.
- Страничка запускает shell script, который запускает процесс деплоймента на сервере.
Итак, теперь обо всем детально.
Сперва заходите на свой сервер и создаете файлик, который будет виден с нет и который будет запускать процесс деплоймента. Я написал его на РНР для простоты, он очень тривиален:
<?php
set_time_limit(0);
if(isset($_POST['payload'])){
$data = json_decode(stripslashes($_POST['payload']));
if($data->ref == "refs/heads/live"){
passthru('sudo /some/path/to/live/script.sh');
} else {
passthru('sudo /some/path/to/staging/script.sh');
}
}
?>
Он проверяет если я сдела пуш в ветку master – значит делает деплоймент бета сервера, если live - значит живой сайт обновляет.
Потом заходим в админку нашего репозитория на гитхабе и указываем ссылку на этот наш скрипт в Post-Receive urls. Почитать детально про Post-Receive Hooks на Githab.
Теперь создаем shell script который будет запускать процесс деплоймента, он тоже простой:
#!/bin/bash PROJDIR="/path/to/project/public_html" LOGFILE="/path/to/project/logs/deploy.log" cd $PROJDIR . ./project-env/bin/activate fab deploy -f $PROJDIR/fabfile.py >> $LOGFILE apache2ctl -k graceful
Собственно скрипт активирует virtualenv(сам fabric установлен в нем, потому так делаю, есил у вас он общесистемный – просто запускаете и все) – и указываю в какой лог складывать результат установки + перезапсук апача в конце.
Ага, еще такая вещь, чтобы с РНР скрипта удалось запустить команду с sudo - в sudoers указал следующее:
www-data ALL =(ALL) NOPASSWD: /some/path/to/live/script.sh www-data ALL =(ALL) NOPASSWD: /some/path/to/staging/script.sh
Так мы разрешаем запускать данные скритп через sudo без пароля для группы www-data.
Сам скрипт fabric достаточно большой чтобы его постить тут, я сейчас опишу что он делает, если кому надо – скину исходник на gist.
Сам скрипт каждый раз клонирует репозиторий с github и складывает в папочку с текущим временем и датой вметос названия и линкует ее в папку current. Также он удаляет старые папки(больше 10 дней помоему). Плюс скрипт линкует все папки/файлы, которых нет в репозитории.
По идее в скрипт можно добавить еще обнолвение базы данных(south или просто выполнение sql файлов) или например обновление библиотек в virtualenv из файлика requirements.txt. Но пока я оставил все максимально просто, изменения в структуре бд я делаю не так часто и надежнее сделать их руками. То же самое касается новых библиотек.
В итоге процесс обновления новой версии на staging или production занимает от силы секунд 20-30 после пуша на гитхаб, что очень и очень подталкивает делать обновления на живом сайте как можно чаще :)

