289 слов | 1 минута

gitlab-ci.yml

Для копирования исходников лучше использовать rsync. Эта утилита позволяет копировать только изменившиеся файлы. Например, для копирования файлов из репозитория в /var/www/project необходимо добавить такую команду в секцию script:

stages:
  deploy
deploy-job:
  stage: deploy
  script:
    echo "Deploying application..."
    rsync -av --no-perms --no-owner --no-group --exclude ".git*" $CI_PROJECT_DIR/ /var/www/project
    echo "Application successfully deployed."

LFTP

Эти переменные будут доступны в yml файле:

  • $PROD_FTP_USER
  • $PROD_FTP_PASSWORD
  • $PROD_FTP_SERVER
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"

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

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

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

#...
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"

RSYNC

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 — пасс к хостингу
  • $SSH_ANGERRO_USER — логин к хостингу
  • $SSH_ANGERRO_SERVER — адрес сервера

Минусы такого способа деплоя только в одном: если в GIT-е какой-либо файл был переименован/удалён — деплоер этого не сделает, т.к. он просто копирует репозиторий с Gitlab-а на удалённый сервер, не трогая остальные файлы на удалённом сервере (которых нет в репозитории).

Мануал по утилите