Статьи

Развертывание приложений одним щелчком мыши с помощью Git-хуков на стороне сервера

конспект

Этот пост показывает пользователю, как развернуть простой веб-сайт, используя не более чем git post-receive. Он охватывает достаточно справочной информации, чтобы читатель мог пойти дальше и расширить свои знания, если позволяет время.

Развертывание в один клик

Как часто мы говорим проповедовать мантру развертывания одним щелчком мыши ? Каждый проект? Каждый день? Каждый коммит? Если мы похожи друг на друга, вы легко отождествите себя с одним или несколькими из них. Мы все были в ролях или имели проекты, в которых нам приходилось прыгать через несколько циклов, чтобы развернуть наше приложение в одной или нескольких средах.

Мы знаем, что в конечном итоге это отвлекает от того, что у нас получается лучше всего: дизайн и разработка приложений . Мы знаем, что мы должны сосредоточиться на других областях, таких как архитектура , тестирование и дизайн . Тем не менее, мы постоянно сталкиваемся с мелочами копирования файлов, запуска сценариев и так далее. Мы постоянно увязли в задачах, которые всегда должны быть автоматизированы .

Возможно, вы знакомы с одним из следующих сценариев:

  • После контрольного списка развертывания
  • SSH’ing для удаленного блока и запуска набора сценариев
  • FTP-файлы вручную на удаленный сервер

Я надеюсь, что вы не делаете последний …

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

Недавно я прочитал пост Тима Борончика Git Hooks for Fun и Profit здесь на Sitepoint и подумал, что если . Я прочитал руководство по использованию git-хуков и черпал вдохновение из поста Тима, думая, что должен быть способ автоматизировать развертывание удаленного веб-приложения с их помощью.

Я поставил перед собой простую, ясную цель:

Мне нужно будет только запустить git push, и о развертывании позаботятся, без моего участия.

Друзья смотрели на меня немного сомнительно, когда я говорил об этом; но я был вдохновлен Обоснованно, на этом этапе вы можете задаться вопросом, почему бы просто не использовать сервер непрерывной интеграции (CI), такой как Jenkins или Hudson, или сервис, подобный CodeShip.io ? Это хороший вопрос, и если вы об этом подумали, то указывает на это. Многие этого не делают .

Почему бы не использовать один? Как сказала Бет Такер-Лонг в своем выступлении в PHPUK в прошлом году , не все потребности настолько сложны или сложны, или могут оправдать затраты на внедрение.

Итак, в сегодняшнем посте мы начинаем серию статей о том, как git-хуки могут помочь вам реализовать простые и эффективные процессы развертывания. Сегодня самое простое из всего.

Как это будет работать?

Он состоит из 3 частей:

  1. Рабочий репозиторий
  2. Удаленный, голый, хранилище
  3. Рабочий каталог (ваш развернутый сайт или тестовая ветка)

Мы разработаем наше приложение как обычно, в нашем локальном рабочем каталоге и отправим на удаленный, как обычно, (например, Github , BitBucket и т. Д.). Удаленный репозиторий не будет стандартным репозиторием разработки. Это должно быть то, что называется пустым хранилищем , которое git scm описывает как:

хранилище, которое не содержит рабочий каталог

Если это кажется немного запутанным, это совершенно нормально. Я много читал, когда понял, что такое настройка. Во время этого исследования я нашел цитату из bitflop.com, которая объясняет это довольно кратко.

В Git вы должны использовать только «голое» хранилище, чтобы клонировать и извлекать из, и нажимать на. У него нет извлеченного дерева, поэтому он просто делает то, что условно делает «сервер» в централизованной VCS — записывает коммиты, ветки и т. Д., Когда вы нажимаете на него, и дает вам последние версии, когда вы клонируете или извлекаете из Это.

Так что в нашем голом репозитории мы не сможем редактировать файлы и вносить изменения. Мы должны просто отправить наши последние изменения в эти рабочие каталоги и развернуть их в нашем рабочем каталоге. Если это поможет, используйте изображение ниже, чтобы осмыслить это.

Настройка удаленного репозитория

В целях этой статьи я предполагаю, что вы используете сервер Linux (Debian) и что удаленный репозиторий будет храниться в /opt/git Мы назовем это simpleapp.git Я добавил .git

Используя эти предположения, мы запускаем следующие команды для настройки удаленного репозитория:

 $ mkdir -p /opt/git
$ cd /opt/git
$ git clone --bare simpleapp simpleapp.git
Initialized empty Git repository in /opt/git/simpleapp.git/

Когда это закончится, если вы ls.git Это прекрасно, поскольку рабочий каталог в данном случае фактически является развернутым каталогом.

Крюк после получения

С настройкой удаленного репозитория, мы затем добавляем ловушку git post-receive. Я предоставил один пример в post-receive.sh

 #!/bin/sh
# 
## store the arguments given to the script
read oldrev newrev refname

## Where to store the log information about the updates
LOGFILE=./post-receive.log

# The deployed directory (the running site)
DEPLOYDIR=/var/www/html/simpleapp

##  Record the fact that the push has been received
echo -e "Received Push Request at $( date +%F )" >> $LOGFILE
echo " - Old SHA: $oldrev New SHA: $newrev Branch Name: $refname" >> $LOGFILE

## Update the deployed copy
echo "Starting Deploy" >> $LOGFILE

echo " - Starting code update"
GIT_WORK_TREE="$DEPLOYDIR" git checkout -f
echo " - Finished code update"

echo " - Starting composer update"
cd "$DEPLOYDIR"; composer update; cd -
echo " - Finished composer update"

echo "Finished Deploy" >> $LOGFILE

Этот скрипт, написанный на bash, будет запущен после того, как push-уведомление получено удаленным репозиторием. Он управляет всем процессом развертывания для нас, состоящим из следующих шагов:

  1. Обновите код в развернутом каталоге до последней версии.
  2. Запустите composer install

Давайте посмотрим на это по частям:

 read oldrev newrev refname

Здесь мы храним три аргумента, переданные скрипту post-receive при его вызове. Эти:

  • Предыдущий коммит SHA1 хеш
  • Последний коммит SHA1 хеш
  • Refname (содержащий информацию о ветке)

Это помогает отследить, что развертывается, и выполнить откат, если вам нужно это сделать. Однако этот скрипт не обрабатывает откат.

 LOGFILE=./post-receive.log
DEPLOYDIR=/var/www/html/simpleapp

Затем мы устанавливаем переменную для записи результатов развертывания и каталога развертывания.

 echo -e "Received Push Request at $( date +%F )" >> $LOGFILE
echo " - Old SHA: $oldrev New SHA: $newrev Branch Name: $refname" >> $LOGFILE
echo "Starting Deploy" >> $LOGFILE

Здесь мы регистрируем, когда был получен push-запрос, и подробно о нем. Таким образом, если нам потребуется отладка, у нас будет соответствующая информация и быстрое сообщение о том, что мы начинаем процесс развертывания.

 echo " - Starting code update"
GIT_WORK_TREE="$DEPLOYDIR" git checkout -f
echo " - Finished code update"

Здесь мы сообщаем git, где находится рабочее дерево, и даем команду git извлекать последнюю копию кода в этот каталог, удаляя любые изменения, которые могли быть сделаны вручную.

 echo " - Starting composer update"
cd "$DEPLOYDIR"; composer update; cd -
echo " - Finished composer update"

Теперь, когда код обновлен, так как я использую composer для управления зависимостями, мы запускаем composer updatecomposer.json

 echo "Finished Deploy" >> $LOGFILE

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

  • Очистка и предварительный прогрев каталогов кеша
  • Запуск миграций базы данных
  • Запуск юнитов и регрессионные тесты
  • Проверка разрешений на ключевые каталоги

Однако это простой пример, и я не хочу отвлекать вас от основной цели. В каталоге hookspost-receivepost-receive.sh Вам нужно всего лишь изменить одну переменную, DEPLOYDIR

Измените его в соответствии со своими потребностями, и не забудьте сделать файл исполняемым, иначе он не запустится. Если вы не знакомы с тем, как это сделать, это выглядит следующим образом:

 chmod +x post-receive

Пользователь Git

На удаленном сервере остался один шаг, пользователь git. Это пользователь, который будет управлять процессом и который мы будем аутентифицировать. Поэтому, если он еще не существует, выполните следующую команду, чтобы создать его:

 sudo adduser git

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

Примечание. Если у вас его нет или вы с ним не знакомы, это превосходное краткое руководство от GitHub поможет вам в его создании.

Самый простой способ скопировать открытый ключ — это копирование содержимого между сеансами терминала. Поэтому скопируйте содержимое ~ / .ssh / id_rsa.pub через scp или терминальную сессию на удаленный сервер и добавьте их в удаленный файл authorized_keys.

Затем на своем локальном компьютере проверьте, что теперь вы можете использовать ssh для удаленного блока, выполнив следующую команду, заменив remoteserver

 ssh git@remoteserver 

Все хорошо, вам не предлагается имя пользователя и пароль. Затем убедитесь, что у пользователя git есть необходимые разрешения как для каталога /opt/git/simpleapp

Добавление удаленного репозитория

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

 git remote add test git://remoteserver/opt/git/simpleapp.git

Затем убедитесь, что он на месте:

 git remote

После этого все, что нам нужно сделать, — это начать разработку нашего приложения и продвигаться по мере необходимости.

В заключение

Я понимаю, что это очень много, так как это довольно сложный процесс, по крайней мере, на первый взгляд. Однако, как и в Linux, после того, как вы все настроите, большинство работы закончится.

Как вы думаете? Дайте мне знать, что еще вы хотели бы увидеть. Я надеюсь, что эта статья показала вам, что автоматическое развертывание возможно и просто.

Вы уже сделали это? Вы подошли к этому по-другому? Вы можете сделать лучше? Дайте мне свои мысли в комментариях.