Автоматический деплой с помощью Git, легко и просто
Автоматический деплой из Git? Нет ничего проще!
Cделаем из Git быструю и удобную замену FTP, rsync или чем раньше было принято пользоваться для выгрузки исходников на целевой сервер.
В чём соль?
Огромный плюс такого подхода: вам не нужны никакие дополнительные действия на сервере кроме настройки хуков Git, которые вызываются при git push
. Забудьте о мутных шелл-скриптах, которые невозможно сходу понять. Забудьте повышении прав для скриптов через sudo
как о страшном сне. Забудьте о безпарольных ssh-ключах для доступа к GitHub и о других неприятных компромиссах. Всё это не нужно. Лишь бы на сервере был Git.
Приступим
На целевом сервере нам нужен репозитарий. Можно пустой.
~/www$ git init
Initialized empty Git repository in /home/example.com/www/.git/
В нём разрешим перезапись текущей ветки.
git config receive.denyCurrentBranch ignore
Добавим хук для сохранения локальных правок.
tee .git/hooks/pre-receive <<EOF
#!/bin/sh
cd ..
GIT_DIR='.git'
env -u GIT_QUARANTINE_PATH git stash save --quiet
git stash show || true
EOF
И хук для развертывания самого последнего коммита в текущей ветке.
tee .git/hooks/post-receive <<EOF
#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard
git stash pop --quiet || git reset --hard
EOF
Без бита исполнения Git попросту проигнорирует эти файлы, потому установим его.
chmod +x .git/hooks/pre-receive .git/hooks/post-receive
Теперь расскажем локальному репозитарию об удаленном.
git remote add --track master origin example.com@server.example.net:www
Загрузим основную ветку на целевой сервер.
git push --set-upstream origin master
При первом пуше Git может ругаться на отсутствие HEAD
, это нормально.
Что дальше
Дальнейшая работа происходит обычным образом.
git pull
git add -p
git commit
...
git push
Последняя команда выгрузит основную ветку на сервер когда нам это будет нужно.
Аналогично это можно сделать для любой другой ветки заменив master
на ее имя в командах. Репозиторий можно использовать как и любой другой для коллективной разработки.
Стоит отметить этот метод бережно относится к внесенным прямо на сервере изменениям (лучше без них!), сохраняя их и накатывая обратно после развертывания ветки. В случае конфликтов вам нужно будет вручную сделать git stash pop
на сервере и разрешить конфликты.
Что еще?
В конце хука post-receive
можно делать всё, что вам потребно делать при деплое. Например, вызвать make
в котором или перезапускать Passenger, или явно сбрасывать кеш в PHP-FPM (при apc.stat = 0
), или компилировать файлы LESS, или перезапускать демоны на PHP под контролем Supervisor.