0

Вариант обновления сервиса через GIT

Есть в наличии сервис, который активно разрабатывается. Стоит задача обновлять и держать в актуальном состоянии его на тестовом сервере(и впоследствии на продуктивном).
В целом задача не сложная, но есть несколько нюансов, которые надо в процессе решить:

  1. Из GIT не нужно тянуть весь проект, т.к. интересует только серверная часть сервиса, которая лежит в отдельной директории.
  2. Сервис состоит из файла настроек приложения, параметры которого в процессе разработки могу меняться, добавляться, удалятся (в том числе в зависимости от среды — dev или test) и самого кода сервиса.
  3. Сам код и настройки лежат в абсолютно разных директориях.

Я для себя придумал следующую схему:
Есть некая директория, где лежит git репозиторий, причем только интересующая меня директория с серверной частью. Рядом лежит скрипт, который осуществляет деплой приложения, а именно получает новую версию из GIT, подставляет нужные настройки в файл конфигурации в зависимсти от того это test или prod среда (база данных, количество workers, уровень логирования и т.д). Раскладывает файлы в нужные директории, перезапускает сервис, проверяет, что все запустилось. Далее подробности.

Установка и настройка git

У нас используется gitlab как единый репозитарий кода, именно с него и буду получать код.

Сначала все как обычно. Создаю директорию, где будет лежать код с gitlab и скрипт деплоя.
# mkdir -p /usr/adm/scripts/deploy/notifier
Делаю там пустой репозитарий:
# cd /usr/adm/scripts/deploy/notifier
# git init
# git remote add origin :user/notification.git
Далее идут интересности. Нужно сделать так, что бы c репозитария тащился не весь код, а только нужные директории. Для этого:
Включаю возможность sparce-checkout в git
# git config core.sparsecheckout true
Добавляю необходимые директории в .git/info/sparse-checkout
# echo ws2.php/ >> .git/info/sparse-checkout
Теперь можно делать git pull origin <branch>

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

В примитивном случае скрипт выглядит примерно следующим образом:

#!/bin/sh

SCRIPTHOME="/usr/adm/scripts/deploy/notifier/"
APPDIR=$SCRIPTHOME/ws2.php
BRANCH="my-branch"

APPDST="/opt/ws/Applications/"
APPDSTCONF="/opt/ws/conf/appconf.conf"

# Application settings
APPUSER="appuser"
APPGROUP="appuser"
APPLOGLEVEL="2"
APPTIMER="60"
APPCACHE="40"

cd $SCRIPTHOME
# get new version from gitlab
git pull origin $BRANCH

# replace files in app dirs
# copy application
cp $APPDIR/AppName.php $APPDST
# replace config and place in config dir
cat $APPDIR/appconf.conf | sed "s/user .*;/user $APPUSER;/g;s/group .*;/group $APPGROUP;/g;s/loglevel .*;/loglevel $APPLOGLEVEL;/g;s/timer .*;/timer $APPTIMER;/g;s/cachelifetime .*;/cachelifetime $APPCACHE;/g" > $APPDSTCONF

# restart service
/etc/init.d/appservice restart

if [ -e /var/run/appservice.pid ];then
  echo "=> deploy successful"
  exit 0
else
  echo "=> deploy failed"
  exit 1
fi

Скрипт был упрощен, но общий смысл, надеюсь доносит.

Внимание, было желание перед git pull ... делать git checkout ., но в этом случае с git тянутся все файлы из репозитария.

Почитать подробнее про sparse-checkout

P.S. Решение не претендует на идеальное, но, IMHO имеет право на жизнь. =)
ToDo: Организовать все это дело через SALT для новой установки и последующего использования.

Alexey Egorychev

FreeBSD and Linux sysadmin. Know many systems like mailsystems, DB, WWW stack. Automation with salt, ansible. Monitoring with nagios, zabbix.