MAATRIX / Блог / rclone в Docker Compose: готовый файл

rclone в Docker Compose: готовый файл

MAATRIX

Данные растут, а ручные scp на другой сервер или загрузка бэкапов через веб-интерфейс облака рано или поздно превращаются в забытую рутину — сделали один раз, а через месяц выяснилось, что синхронизация не запускалась три недели. rclone решает это ровно один раз: контейнер поднимается, синхронизирует нужные каталоги с S3-совместимым хранилищем или Google Drive по расписанию и не требует внимания, пока не пришлют алерт. Ниже — рабочий docker-compose.yml, который можно скопировать и адаптировать под свои бакеты.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Зачем заворачивать rclone в контейнер

rclone прекрасно ставится и без Docker — это один бинарник. Но у контейнерного варианта есть практические плюсы:

  • Изоляция версий. На хосте может стоять rclone 1.65 из репозитория Ubuntu, а вам нужны свежие фичи (например, улучшенный --transfers или поддержка нового провайдера) — в контейнере просто берёте актуальный образ.
  • Портируемость конфига. Весь rclone.conf и скрипты синхронизации лежат в одной папке рядом с docker-compose.yml — переносите на другой сервер копированием каталога.
  • Совместное использование с другими сервисами. Если у вас уже есть стек в Docker Compose (БД, MinIO, приложение), логично держать и синхронизацию облака в том же файле — общая сеть, общие volumes, единый docker compose logs.
  • Предсказуемый cron. Планировщик живёт внутри контейнера, а не в системном crontab хоста, который легко потерять при переустановке ОС.

Минус один: sidecar-контейнер с cron внутри — не самый "докерный" паттерн (лучше бы отдельный таймер), но для практической задачи "синхронизировать папку раз в час" это самый быстрый путь к рабочему решению.

Готовый docker-compose.yml

Вариант с официальным образом rclone/rclone, который умеет работать и как демон, и как одноразовая команда. Ниже — сервис, который каждый час копирует локальный каталог с бэкапами в S3-совместимое хранилище через встроенный cron-обвязку в скрипте запуска.

# docker-compose.yml
services:
  rclone-sync:
    image: rclone/rclone:1.68
    container_name: rclone-sync
    restart: unless-stopped
    environment:
      TZ: Europe/Moscow
    volumes:
      - ./rclone.conf:/config/rclone/rclone.conf:ro
      - /var/backups:/data/backups:ro
      - ./scripts/sync-loop.sh:/scripts/sync-loop.sh:ro
    entrypoint: ["/bin/sh", "/scripts/sync-loop.sh"]

Сам скрипт не использует системный cron (в минимальном образе его нет), а держит бесконечный цикл со sleep — этого достаточно для синхронизации раз в час-два и не требует лишних пакетов в контейнере:

#!/bin/sh
# scripts/sync-loop.sh
set -e

INTERVAL="${SYNC_INTERVAL_SECONDS:-3600}"

while true; do
  echo "[$(date -Iseconds)] starting sync"
  rclone sync /data/backups remote:my-bucket/backups \
    --config /config/rclone/rclone.conf \
    --transfers 8 \
    --checkers 16 \
    --log-level INFO \
    --log-file /data/backups/../rclone-sync.log \
    --stats 1m || echo "[$(date -Iseconds)] sync FAILED"
  echo "[$(date -Iseconds)] sync done, sleeping ${INTERVAL}s"
  sleep "$INTERVAL"
done

Если нужен именно cron-синтаксис с точными временами (например, "каждый день в 3:15"), проще использовать образ на базе Alpine с busybox crond или отдельный контейнер ofelia — он умеет запускать команды в других контейнерах по расписанию через сокет Docker, что удобно, если у вас уже несколько разовых задач.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Конфиг rclone.conf для S3 и Backblaze B2

rclone.conf — обычный INI-файл, его проще всего сгенерировать один раз локальной командой rclone config и скопировать на сервер, чем писать вручную. Но структура простая, и для S3-совместимых хранилищ (Amazon S3, MinIO, Backblaze B2, Selectel, Yandex Object Storage) секция выглядит так:

[remote]
type = s3
provider = AWS
access_key_id = AKIA...
secret_access_key = ваш_секретный_ключ
region = eu-central-1
endpoint =
acl = private

Для Backblaze B2 удобнее нативный тип b2 — он быстрее и без S3-обёртки:

[remote]
type = b2
account = 005xxxxxxxxxxxxxxxxxxxx
key = K005xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
hard_delete = true

Для self-hosted MinIO на вашем же сервере (см. отдельную статью про MinIO в Docker Compose) секция почти как S3, но с указанием эндпоинта:

[remote]
type = s3
provider = Minio
access_key_id = minioadmin
secret_access_key = ваш_пароль
endpoint = http://minio:9000
region = us-east-1

Обратите внимание: если MinIO работает в том же docker-compose проекте, эндпоинтом должно быть имя сервиса (minio), а не localhost — контейнеры общаются между собой по внутренней сети Docker Compose, и для этого их достаточно объявить в одном файле или подключить к общей external network.

Google Drive: нюанс с авторизацией

С Google Drive сложнее, потому что нужен OAuth-токен, а получить его в headless-контейнере без браузера напрямую нельзя. Практический путь:

  1. На локальной машине с браузером выполните rclone config и пройдите авторизацию для типа drive — это создаст токен в ~/.config/rclone/rclone.conf.
  2. Скопируйте получившуюся секцию [gdrive] целиком на сервер в тот же rclone.conf, который монтируется в контейнер.
  3. Токен обновляется автоматически (rclone сам делает refresh), но сам файл rclone.conf при этом меняется на диске — значит, монтировать его нужно не :ro, а в режиме чтения-записи, иначе после первого рефреша rclone не сможет сохранить новый токен и синхронизация начнёт падать через несколько недель.
volumes:
  - ./rclone.conf:/config/rclone/rclone.conf   # без :ro для Google Drive

Для одноразовых задач (не сервисный аккаунт) у Google Drive есть квота на количество запросов API в сутки — при большом количестве мелких файлов синхронизация может упираться в rate limit. Флаг --drive-chunk-size 64M и укрупнение батчей через --transfers умеренно помогают, но для по-настоящему больших объёмов (сотни тысяч файлов) Google Drive — не лучший вариант хранения бэкапов; S3-совместимое хранилище ведёт себя предсказуемее.

sync, copy и bisync: в чём разница и когда что использовать

Это самое важное решение в конфигурации — от него зависит, не потеряете ли вы данные.

КомандаПоведениеКогда использовать
rclone copyКопирует новые/изменённые файлы, ничего не удаляет в приёмникеБезопасный вариант по умолчанию, если не уверены
rclone syncДелает приёмник зеркалом источника — удаляет в приёмнике то, чего нет в источникеКогда источник — источник истины (например, каталог бэкапов с ротацией)
rclone bisyncДвусторонняя синхронизация, отслеживает изменения на обеих сторонахОбщие рабочие каталоги, куда пишут и локально, и в облаке

Для бэкапов с ротацией (например, скрипт удаляет файлы старше 30 дней локально) sync — то, что нужно: облако будет отражать актуальное состояние. Но именно поэтому первый запуск sync стоит делать с флагом --dry-run, чтобы увидеть, что именно будет удалено, прежде чем запускать по-настоящему:

rclone sync /data/backups remote:my-bucket/backups --dry-run -v

Если в вашем случае удаление в облаке недопустимо в принципе (например, ведёте архив версий), используйте copy и настройте на стороне бакета собственную политику хранения версий (lifecycle rules у S3-совместимого хранилища).

Мониторинг и типичные ошибки

Контейнер, который тихо перестал синхронизировать, опаснее отсутствия синхронизации вообще — вы узнаёте о проблеме только когда бэкап понадобился. Практический минимум:

  • Проверяйте код завершения. В скрипте выше ошибка синхронизации логируется, но не останавливает цикл — это осознанный компромисс (лучше пропустить один цикл, чем упасть насовсем), но тогда нужен внешний мониторинг.
  • Healthchecks.io или аналог. Добавьте curl пинг в конец успешного прогона — если пинг не пришёл вовремя, придёт алерт (подробнее в статье про мониторинг cron-задач через healthchecks.io):
rclone sync /data/backups remote:my-bucket/backups --config /config/rclone/rclone.conf \
  && curl -fsS -m 10 https://hc-ping.com/ваш-uuid
  • docker compose logs -f rclone-sync — быстрый способ увидеть, реально ли идёт синхронизация или контейнер завис на этапе аутентификации.
  • Частые ошибки: 403 Forbidden от S3 почти всегда означает неверный access_key/secret_key или отсутствие прав на bucket у ключа; context deadline exceeded — сетевая проблема или слишком агрессивные --transfers при слабом канале, стоит снизить до 4; для Google Drive userRateLimitExceeded — упор в квоту API, решается снижением параллелизма и увеличением интервала.
  • Место на диске. Лог-файл при --log-level INFO и большом количестве файлов растёт быстро — добавьте logrotate на хосте или ограничьте размер через --log-file в связке с внешней ротацией, иначе через пару месяцев лог сам займёт заметную часть диска.

Ресурсы: сколько CPU и RAM закладывать

rclone не требователен, но потребление растёт с количеством параллельных потоков и размером кэша чексумм:

  • Для синхронизации нескольких гигабайт бэкапов раз в час хватает 1 vCPU и 512 МБ RAM с запасом.
  • При --transfers 8 и большом количестве мелких файлов (десятки тысяч) полезно выделить 1-2 ГБ RAM — rclone держит в памяти списки файлов для сравнения источника и приёмника.
  • Сетевой канал обычно узкое место раньше CPU: если сервер отдаёт бэкапы на внешнее S3-хранилище, сама синхронизация упирается в исходящую полосу, а не в ресурсы контейнера.

Для типичной задачи "бэкапы БД + конфиги, синхронизация раз в час" достаточно самого младшего VPS — нет смысла переплачивать за выделенные ядра ради rclone-контейнера, если на том же сервере уже крутится основное приложение.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли монтировать облако как файловую систему вместо синхронизации?

Да, у rclone есть команда rclone mount, но она требует FUSE и привилегированного режима контейнера (--cap-add SYS_ADMIN --device /dev/fuse), что заметно повышает поверхность атаки. Для регулярных бэкапов sync/copy проще и безопаснее.

Что будет, если контейнер перезапустится посреди синхронизации?

rclone не транзакционен на уровне всей операции, но при следующем запуске sync докопирует недостающее и досчитает разницу — частично скопированные файлы просто перезапишутся заново. Прерванная синхронизация не портит уже переданные файлы.

Как хранить ключи доступа безопаснее, чем открытым текстом в rclone.conf?

Можно зашифровать сам конфиг паролем через rclone config (флаг для password-protected config) и передавать пароль контейнеру через переменную окружения RCLONE_CONFIG_PASS, а ещё лучше — через Docker secrets, если сервер уже в режиме Swarm.

Нужен ли отдельный сервер под rclone или можно на том же, что и приложение?

Для большинства проектов rclone-контейнер спокойно живёт на том же сервере, что и основной стек — нагрузка минимальная, а совместное расположение упрощает доступ к локальным каталогам с бэкапами без передачи их по сети.

Чем rclone принципиально отличается от связки aws-cli s3 sync?

rclone работает с десятками провайдеров через единый интерфейс (не только S3-совместимые, но и Google Drive, Dropbox, Backblaze нативно, SFTP и другие), тогда как aws s3 sync жёстко привязан к AWS S3 и S3-совместимым API. Если облако может смениться, rclone экономит переписывание скриптов.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →