GitLab CI/CD FTP deploy

Привет!
Попросили тут помочь с заливкой обновленной версии статичного сайта на шаред хостинг где из доступов есть только FTP.

Можно было просто залить все используя FileZilla/Midnight Commander/etc и забыть об этом, но появился и другой вариант - залить сайт в git-репозиторий и настроить CI/CD для деплоя мастер-ветки.

Инструкция

1. Добавляем реквизиты для доступа к FTP в настройки репозитория в GitLab

1
2
3
4
5
Эти переменные будут доступны в yml-файле

$PROD_FTP_USER
$PROD_FTP_PASSWORD
$PROD_FTP_SERVER

2. Добавляем .gitlab-ci.yml в проект

.gitlab-ci.yml

1
2
3
4
5
6
7
8
9
10
11
before_script:
- 'which lftp || ( apt-get update -y && apt-get install lftp -y )'


deploy_master:
only:
- master
stage: deploy
script:
- lftp ftp://$PROD_FTP_USER:$PROD_FTP_PASSWORD@$PROD_FTP_SERVER -e \
"set ftp:ssl-allow no; mirror --continue --reverse --delete --verbose --exclude=^\.git/$ . /; quit"

Тут мы устанавливаем lftp и затем просто синхронизируем текущую директорию с корневой директорией на FTP. Директорию .git игнорируем и на FTP не заливаем.

Важные моменты

  • set ftp:ssl-allow no отключает проверку SSL-сертификата на FTP-сервере. В моем случае это понадобилось.
  • Скрипт выполняется из директории где находится код проекта, соответственно локальный путь будет .
  • Путь на FTP-сервере в моем случае оказался равен /, но лучше сперва вручную подключиться к FTP и посмотреть его.
  • Ключ --verbose показывает подробности заливки файлов на FTP. Это может быть полезно во время отладки, но если у вас очень много файлов то логи в CI Job будут огромные.
  • Lftp не умеет синкать только изменившиеся файлы, поэтому проект перезаливается полностью каждый раз. Для маленьких проектов это даже плюс, а вот для больших такой вариант не подойдет.

Выводы

Тут конечно намного предпочтительнее был бы вариант с SSH-доступом. Как минимум можно было бы синкать только то что изменилось посредством rsync, а как максимум запускать на проде миграции БД, сборку ресурсов и прочие полезные вещи.

Но в крайнем случае даже с FTP можно настроить автоматический деплой и не заморачиваться с ручной заливкой файлов.

UPD:

Возникла необходимость сохранять на хостинге логи (файлы вида /logs/.send_result_l45fd.log) во время деплоя.

Добавил регулярку для исключения этих файлов:

1
2
3
4
#...
script:
- lftp ftp://$PROD_FTP_USER:$PROD_FTP_PASSWORD@$PROD_FTP_SERVER -e \
"set ftp:ssl-allow no; mirror --continue --reverse --delete --exclude=^logs\/.*\.log$ --exclude=^\.git/$ . /; quit"