Гид по технологиям

rsync в GitLab CI: развёртывание через SSH

• 7 min read • DevOps • Обновлено 10 Dec 2025
rsync в GitLab CI: развёртывание через SSH
rsync в GitLab CI: развёртывание через SSH

Логотип GitLab — стилизованная голова лисы

  • Кратко: интегрируйте rsync в Docker‑запуск GitLab CI, добавив openssh-client и rsync в образ, передав приватный ключ через защищённую переменную и занеся хост в known_hosts. Это даёт быстрые инкрементные развёртывания без больших Docker-образов.
  • Важное: храните приватный ключ как защищённую CI‑переменную, ограничьте его права на целевом сервере и предпочитайте known_hosts вместо отключения проверки хоста.

Быстрые ссылки

  • Pipeline Executors
  • Подготовка
  • Добавление файла pipeline
  • Установка SSH и rsync
  • Управление проверкой хоста
  • Дальнейшие улучшения
  • Плейбук: шаги для развёртывания
  • Критерии приёмки
  • Безопасность и соответствие
  • Часто задаваемые вопросы
  • Резюме

rsync — популярная утилита синхронизации файлов, использующая дельта‑алгоритм для минимизации потребления трафика. Частое применение — развёртывание собранного сайта на удалённый production‑сервер. Ниже объяснено, как сочетать гибкость rsync с автоматизацией GitLab CI.

Pipeline Executors

GitLab CI поддерживает несколько типов исполнителей (executors). Они определяют среду выполнения задач.

shell
  • shell — исполнитель по умолчанию, выполняет команды прямо на хосте. Удобен, если на runner уже установлен rsync и ssh.
  • Преимущество: можно использовать любые команды хоста без допнастроек.
  • Недостаток: слабая изоляция, риск загрязнения хоста.

Лучшей практикой обычно является использование

docker
  • docker — создаёт чистый контейнер для каждой CI‑задачи. Изоляция лучше, работа безопаснее для хоста.
  • Минус: минимальные базовые образы часто не содержат rsync и ssh.

Ниже показано, как добавить rsync в Docker‑задачу. Предполагается, что у вас есть Docker‑runner и проект в GitLab.

Подготовка

Нужна пара SSH‑ключей, если вы будете подключаться к удалённому хосту по SSH. Создать пару можно так:

ssh-keygen -t rsa

Скопируйте публичный ключ на сервер (в зависимости от сервера используйте ssh-copy-id или вручную добавить в ~/.ssh/authorized_keys).

Содержимое приватного ключа загрузите в буфер обмена и затем — в CI‑переменную проекта:

cat ~/.ssh/id_rsa | xclip -selection c

В GitLab: Settings → CI/CD → Variables. Создайте переменную, например SSH_PRIVATE_KEY, и вставьте весь приватный ключ включая строки —–BEGIN RSA PRIVATE KEY—– и —–END RSA PRIVATE KEY—–. Установите флажки “Protected” и “Masked” при необходимости.

Скриншот добавления переменной GitLab CI

После этого GitLab сможет инжектировать ключ в контейнер во время выполнения pipeline.

Добавление файла pipeline

GitLab CI использует файл .gitlab-ci.yml в корне репозитория. Пример минимальной задачи, которая будет пытаться выполнить rsync:

deploy:
  stage: deploy
  image: alpine:latest
  script:
    - rsync -atv --delete --progress ./ user@example.com:/var/www/html

Этот пример синхронизирует содержимое рабочей директории на сервер example.com в /var/www/html, но упадёт на этапе запуска, потому что в alpine:latest не установлен rsync и клиент SSH.

Установка SSH и rsync

Alpine — хороший выбор для контейнера благодаря маленькому размеру. Добавим пакеты openssh-client и rsync, затем запустим ssh‑агент и зарегистрируем приватный ключ из CI‑переменной.

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk update && apk add --no-cache openssh-client rsync
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  script:
    - rsync -atv --delete --progress ./ user@example.com:/var/www/html

Пояснения:

  • apk add устанавливает openssh-client и rsync.
  • eval $(ssh-agent -s) запускает ssh‑агент.
  • echo “$SSH_PRIVATE_KEY” | ssh-add - — добавляет приватный ключ в агент. Команда tr -d ‘\r’ полезна при переносе ключа между Windows и Unix.

Управление проверкой хоста

При первом подключении SSH интерактивно запросит подтверждение ключа хоста. CI‑среда не позволяет отвечать на такие запросы, поэтому есть два пути:

  1. Отключить строгую проверку ключа — быстро, но менее безопасно.
- echo "Host *\n  StrictHostKeyChecking no\n  UserKnownHostsFile=/dev/null" >> ~/.ssh/config
  1. Предварительно зарегистрировать ключ хоста в known_hosts (рекомендуется).
  • На локальной машине выполните:
ssh-keyscan -p 22 example.com
  • Скопируйте полученную строку и создайте CI‑переменную SSH_HOST_KEY. В pipeline добавьте:
- mkdir -p ~/.ssh
- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts

Использование known_hosts даёт гарантию, что вы подключаетесь к ожидаемому серверу и не отключает проверку, что повышает безопасность.

Полный пример .gitlab-ci.yml с переменными

variables:
  DEPLOY_USER: "user"
  DEPLOY_HOST: "example.com"
  DEPLOY_DIR: "/var/www/html"

stages:
  - deploy

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk update && apk add --no-cache openssh-client rsync
    - mkdir -p ~/.ssh
    - echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  script:
    - rsync -az --delete --progress ./ "$DEPLOY_USER"@"$DEPLOY_HOST":"$DEPLOY_DIR"
  only:
    - main

Рекомендуем вынести DEPLOY_* переменные в настроечные CI‑переменные проекта, чтобы не держать их в репозитории.

Дальнейшие улучшения и альтернативы

  • Использовать специализированный Docker образ, в который уже включены rsync и ssh, чтобы уменьшить шаги установки в каждом pipeline.
  • Построить stage “build image” в CI, который собирает образ с нужными утилитами и пушит его в private registry — ускоряет последующие pipelines.
  • Рассмотреть артефакты GitLab (artifacts) и хранение билдов в контейнерном реестре/объектном хранилище, если развёртывание требует дополнительных шагов.
  • Альтернатива rsync: scp (простой, но менее эффективен), lftp/mirror (для FTP), SFTP или специализированные инструменты развёртывания (Ansible, Capistrano).

Когда это не подходит (контрпримеры)

  • Если у вас масштабируемая инфраструктура с балансировкой нагрузки и несколькими узлами — лучше использовать более управляемые механизмы (CI → артефакт → orchestration или периодический pull с каждой ноды).
  • Если нужно гарантированное атомарное переключение на новый релиз (без промежуточных частично обновлённых файлов), используйте подход с развёртыванием в отдельную директорию и атомарным symlink‑переключением.
  • Для сложных миграций баз данных и rollbacks rsync сам по себе недостаточен.

Плейбук: шаги для развёртывания (SOP)

  1. Локально: сгенерировать SSH‑ключи, проверить доступ к серверу.
  2. Локально: получить строку known_hosts через ssh-keyscan и сохранить.
  3. В GitLab: добавить CI‑переменные: SSH_PRIVATE_KEY (protected, masked), SSH_HOST_KEY (protected).
  4. Добавить .gitlab-ci.yml с установкой openssh-client и rsync.
  5. Настроить user с минимальными правами на сервере — ограничить команды через authorized_keys опции при необходимости.
  6. Прогнать pipeline на staging‑ветке.
  7. Проверить файлы на сервере, проверить логи rsync –progress.
  8. Перекатить изменения в main / production.

Роль‑ориентированные чеклисты

DevOps:

  • Проверить runner (docker executor) и доступ к registry.
  • Настроить секреты и права доступа в GitLab.
  • Проверить настройки SSH на целевом сервере.

Разработчик:

  • Убедиться, что сборка помещается в рабочую директорию.
  • Протестировать локально команду rsync.

Системный администратор:

  • Ограничить права ключа в authorized_keys (no-port-forwarding,no-X11-forwarding,command=”…” по необходимости).
  • Проверить место на диске и права директорий назначения.

Критерии приёмки

  • Pipeline успешно проходит на ветке deploy/main.
  • Файлы на сервере совпадают с артефактом сборки (проверено checksum/списком файлов).
  • Права и владельцы файлов установлены корректно.
  • Нет предупреждений SSH о неподтверждённых ключах.
  • Развёртывание откатывается/исправляется простым запуском предыдущей версии (описан rollback).

Откат (runbook/rollback)

  1. Если развёртывание нарушило работу, приостановите CI‑триггеры для main.
  2. Если у вас есть snapshot каталога (например, /var/www/html_prev), выполните rsync со старой копии:
rsync -az --delete /var/www/html_prev/ user@example.com:/var/www/html/
  1. Альтернатива — восстановление из резервной копии или переключение симлинка на предыдущую папку release.
  2. Проанализировать логи rsync и системные логи сервера, восстановить данные, если нужно.

Безопасность и соответствие

  • Храните SSH_PRIVATE_KEY как Protected и Masked переменные в GitLab.
  • Ограничьте права ключа на сервере. Пример записи в ~/.ssh/authorized_keys:
from="CI_SERVER_IP_RANGE",no-pty,no-agent-forwarding,no-port-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
  • Не отключайте StrictHostKeyChecking в production. Вместо этого используйте SSH_HOST_KEY.
  • Рассмотрите использование временных/эпhemeral ключей через секретные хранилища (HashiCorp Vault, AWS Secrets Manager) для повышения безопасности.
  • Храните логи и аудит подключения отдельно, чтобы отслеживать доступ.

Шпаргалка: часто используемые флаги rsync

  • -a — archive (рекурсивно, сохраняет права, симлинки и т.д.)
  • -z — сжатие данных при передаче
  • -v — verbose
  • -t — сохранять время модификации
  • –delete — удалять на целевом стороне файлы, отсутствующие в исходной директории
  • –progress — показывать прогресс передачи
  • –exclude=”node_modules” — исключить директорию

Пример: rsync -az –delete –exclude=”.git” ./ user@host:/var/www/html

Decision flow (выбор стратегии)

flowchart TD
  A[Нужен быстрый простой деплой?] -->|Да| B[Использовать rsync в GitLab CI]
  A -->|Нет, масштабируемая инфраструктура| C[Рассмотреть артефакты и orchestration]
  B --> D{Docker runner?}
  D -->|Да| E[Добавить openssh-client и rsync в before_script]
  D -->|Нет, shell runner| F[Запустить напрямую, убедиться в безопасности хоста]
  E --> G{Безопасность важна?}
  G -->|Да| H[Использовать SSH_HOST_KEY и ограниченные ключи]
  G -->|Нет| I[Можно временно отключить StrictHostKeyChecking]

Часто задаваемые вопросы

Нужно ли ставить rsync в каждый pipeline‑контейнер?

Не обязательно: можно собрать собственный базовый образ с rsync/ssh и хранить его в registry, чтобы ускорять pipelines.

Можно ли использовать deploy key вместо пользовательского SSH‑ключа?

Да. Deploy key (ключ, добавленный в репозиторий или на сервер) — хорошая практика: создайте ключ с минимальными правами и используйте его только для доступа к папке deploy.

Как защитить приватный ключ в GitLab?

Отключите возможность отображать переменной (Mask) и сделайте её Protected, чтобы переменная была доступна только веткам/тегам с защитой.

Факто‑бокс: главные идеи

  • rsync экономит трафик за счёт передачи только изменённых частей файлов.
  • Docker‑runner даёт изоляцию, но требует явной установки зависимостей.
  • Всегда предпочитайте known_hosts отключению StrictHostKeyChecking для production.

Шаблонные проверки и тесты приёмки

  • Тест 1: Pipeline завершается с кодом 0 на ветке deploy.
  • Тест 2: Файл index.html обновлён на целевом сервере, timestamp совпадает с локальным.
  • Тест 3: В логах нет сообщений о неизвестном хосте.

Краткое резюме

Интеграция rsync в GitLab CI при помощи Docker‑исполнителя требует нескольких дополнительных шагов: установка openssh-client и rsync в контейнере, безопасная передача приватного ключа через CI‑переменную и регистрация ключа хоста в known_hosts. Это даёт быстрые и эффективные развёртывания, если применять базовые меры безопасности и организовать повторно используемый образ/стадию для подготовки среды.

Важно: для production используйте ограниченные ключи, храните секреты в защищённых переменных и тестируйте откаты заранее.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро