Работа с GIT-ом даёт возможность разработчику не бояться что-либо поломать. Это реально здорово! Вот только в последнее время мне надоело ручками через WinSCP выкатывать последние обновления на хостинг в рамках изменений в master
ветке. Хотелось бы это как-то автоматизировать…
Собственно задача состоит в следующем:
- создать механизм выгрузки репозитория из GitLab на удалённый хостинг
- Выгрузка должна срабатывать после пуша коммита/коммитов в ветку
master
- файлы и директории на удалённом хостинге, которые отсутствуют в репозитории не должны удаляться
Для реализации задачи я воспользовался встроенной в Gitlab CI системой. Кратко напомню, что это выполнение инструкций, определённых в файле .gitlab-ci.yml
Рассмотрим его содержимое:
image: ubuntu:19.10 deploy: before_script: - apt-get update -y - apt-get install -y rsync sshpass #Передаем пароль из переменной окружения - export SSHPASS=$SSH_ANGERRO_PSWD script: #синхронизация (push rsync) - rsync --recursive --links --owner --group --times --verbose --no-perms --chmod=D0700,F0700 --rsh="sshpass -e ssh -o StrictHostKeyChecking=no" --exclude '.git' --exclude '.gitlab-ci.yml' ./ $SSH_ANGERRO_USER@$SSH_ANGERRO_SERVER:tickets/public_html/ only: - master
image: ubuntu:19.10
— мне привычнее работать с образом Linux Ubuntu, поэтому я выбрал выполнение задачи именно на Ubuntu-е
deploy
— название задачи
before_script
— команды, которые будут выполнены до запуска основного скрипта задачи.
Здесь производится обновление apt-get-а (программы обновления/установки/удаления программных пакетов в Linux) и установка двух программ: rsync
и sshpass
rsync
— программа для синхронизации файлов и директорий (именно она и будет реализовывать деплой на удалённый сервер)
sshpass
— утилита, которая позволяет выполнять команды на удалённом сервере по SSH без ввода пароля вручную.
Следующая команда:
export SSHPASS=$SSH_ANGERRO_PSWD
записывает пароль к удалённому серверу в переменную SSHPASS, которой пользуется утилита sshpass
$SSH_ANGERRO_PSWD
же определяется отсюда:
На этой странице Gitlab-а можно создать сколько угодно переменных. Мне же потребовалось только 3:
$SSH_ANGERRO_PSWD
— пасс к хостингу$SSH_ANGERRO_USER
— логин к хостингу$SSH_ANGERRO_SERVER
— адрес сервака
Запись
only: - master
означает, что выполнять задачу требуется только в случае пуша в master
ветку.
Команда деплоя
Переходим к разбору команды деплоя:
- rsync --recursive --links --owner --group --times --verbose --no-perms --chmod=D0700,F0700 --rsh="sshpass -e ssh -o StrictHostKeyChecking=no" --exclude '.git' --exclude '.gitlab-ci.yml' ./ $SSH_ANGERRO_USER@$SSH_ANGERRO_SERVER:tickets/public_html/
Здесь запускается rsync
, который выгружает всё из директории ./
репозитория (т.е. всю репу) в директорию tickets/public_html/
на моём удалённом сервере.
Ключи --recursive --links --owner --group --times --verbose --no-perms --chmod=D0700,F0700
означают, что rsync
будет выгружать данные по определённым правилам (сохранение символических ссылок, рекурсивный перебор, сохранение времени и т.п.) — подробнее можете почитать в мануале по этой утилите.
Ключ --rsh
определяет удалённую оболочку для подключения. В нашем случае это sshpass
(для запоминания пароля) и ssh
(для передачи данных на удалённый сервер)
Ключи --exclude
определяют те директории/файлы, которые не требуется выгружать.
Результат
После пуша в master
ветку создаётся задача в разделе CI/CD -> Jobs:
Результат каждого деплоя логируется и если что-то пошло не так — можно посмотреть.
Минусы такого способа деплоя только в одном: если в GIT-е какой-либо файл был переименован/удалён — деплоер этого не сделает, т.к. он просто копирует репозиторий с Gitlab-а на удалённый сервер, не трогая остальные файлы на удалённом сервере (которых нет в репозитории).