Duplicati в Docker Compose: готовый файл
Настраивать бэкапы через cron и голые скрипты удобно, пока их не станет пять на разных серверах — тогда начинаешь забывать, что и когда бэкапится, и узнаёшь о проблеме уже при восстановлении. Duplicati решает это веб-интерфейсом: расписание, шифрование, дедупликация и десяток вариантов хранилища настраиваются кликами, а не строками в crontab. Ниже — рабочий docker-compose.yml, который можно поднять на VPS за несколько минут, и разбор того, что стоит донастроить руками, чтобы бэкап реально спасал при аварии.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Duplicati и когда он уместен
Duplicati — open-source инструмент резервного копирования с веб-интерфейсом на .NET/Mono, который умеет:
- инкрементальные бэкапы с блочной дедупликацией (после первого полного снимка передаются только изменённые блоки);
- AES-256 или GPG-шифрование архивов перед отправкой в хранилище;
- расписания любой сложности (раз в час, по дням недели, с исключением праздников);
- десятки бэкендов: локальная папка, SFTP, WebDAV, S3-совместимое хранилище, Backblaze B2, Google Drive и другие;
- восстановление отдельных файлов или всего снимка через тот же веб-интерфейс, без консоли.
Это не замена дампам БД через pg_dump/mysqldump и не альтернатива снапшотам файловой системы для нагруженных баз — под такие сценарии больше подходят restic или специализированные инструменты уровня БД. Duplicati хорош там, где нужен предсказуемый бэкап файлов, конфигов, Docker-volume'ов и небольших баз с понятным интерфейсом для тех, кто не хочет разбираться в CLI-флагах каждый раз, когда нужно восстановить один файл.
Готовый docker-compose.yml
Используем образ linuxserver/duplicati — он поддерживается активно, имеет предсказуемую структуру каталогов и работает под непривилегированным пользователем через PUID/PGID.
services:
duplicati:
image: lscr.io/linuxserver/duplicati:latest
container_name: duplicati
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Moscow
- CLI_ARGS= #optional
- SETTINGS_ENCRYPTION_KEY=${DUPLICATI_ENC_KEY}
- DUPLICATI__WEBSERVICE_PASSWORD=${DUPLICATI_WEB_PASSWORD}
volumes:
- ./config:/config
- ./backups:/backups
- /srv/data:/source/data:ro
- /srv/docker-volumes:/source/docker-volumes:ro
- /etc:/source/etc:ro
ports:
- "127.0.0.1:8200:8200"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8200"]
interval: 30s
timeout: 10s
retries: 3
Ключевые моменты:
SETTINGS_ENCRYPTION_KEYшифрует локальную базу конфигурации (пароли от хранилищ, ключи шифрования бэкапов) — задайте случайную строку и сохраните её отдельно от сервера, иначе при потере диска конфиг не восстановить.DUPLICATI__WEBSERVICE_PASSWORDзащищает сам веб-интерфейс паролем — без этой переменной панель на 8200 порту открыта всем, у кого есть доступ к сети.- Порт привязан к
127.0.0.1, то есть снаружи недоступен — это сделано намеренно, доступ будет через reverse proxy (см. ниже). - Источники (
/source/...) монтируются в:ro— Duplicati их только читает, что снижает риск случайно что-то сломать в контейнере бэкапа.
Файл .env рядом с compose:
DUPLICATI_ENC_KEY=<сгенерировать: openssl rand -base64 32>
DUPLICATI_WEB_PASSWORD=<длинный пароль>
Запуск:
mkdir -p config backups
docker compose up -d
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПервый запуск и настройка веб-интерфейса
Порт закрыт снаружи, поэтому для первого захода пробросьте его через SSH-туннель:
ssh -L 8200:127.0.0.1:8200 user@your-server-ip
Откройте http://localhost:8200 в браузере — попадёте в панель Duplicati. При первом входе система попросит пароль (тот, что задан в DUPLICATI__WEBSERVICE_PASSWORD), дальше — главный экран со списком задач бэкапа, пока пустым.
Для постоянного доступа без туннеля разумнее поставить reverse proxy с TLS и отдельной авторизацией, а не открывать порт наружу напрямую — Duplicati хранит там пароли от бэкендов, и лишний открытый порт увеличивает поверхность атаки. Пример с Nginx:
server {
listen 443 ssl;
server_name backup.example.com;
ssl_certificate /etc/letsencrypt/live/backup.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/backup.example.com/privkey.pem;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8200;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Basic auth поверх встроенного пароля Duplicati — это два независимых слоя, и потеря одного не открывает доступ полностью.
Настройка задачи бэкапа: источник, назначение, расписание
В интерфейсе: Add backup → Configure a new backup. Мастер проведёт по шагам:
- General — имя задачи и пароль шифрования архива (отдельный от пароля веб-интерфейса, храните в менеджере паролей — без него расшифровать бэкап невозможно).
- Backend — куда складывать снимки. Для локального теста подойдёт
/backupsвнутри контейнера, для продакшена — внешнее хранилище, чтобы бэкап пережил аварию самого сервера:
s3://your-bucket/duplicati?region=eu-central-1
webdav://storage.example.com/duplicati
ssh://user@backup-host//srv/duplicati
- Source Data — что бэкапить, отмечаете смонтированные
/source/data,/source/docker-volumes,/source/etc. - Schedule — периодичность (например, ежедневно в 03:00) и допустимое окно повторной попытки при сбое.
- Options — здесь настраивается retention policy:
keep-time-frames = 1W:1D,1M:1W,1Y:1M
Это правило хранит ежедневные снимки за последнюю неделю, еженедельные за последний месяц и ежемесячные за год — компромисс между глубиной истории и объёмом хранилища. Подбирайте под свои требования к RPO, не копируйте цифры бездумно.
Бэкап Docker volumes и баз данных
Смонтировать /var/lib/docker/volumes напрямую можно, но для баз данных (PostgreSQL, MySQL, MongoDB) файловый снимок «на живую» рискует оказаться несогласованным — файлы БД в момент копирования могут находиться в промежуточном состоянии. Правильный порядок:
#!/bin/bash
# /opt/scripts/pre-backup-dump.sh — запускать перед бэкапом Duplicati
docker exec postgres-db pg_dumpall -U postgres > /srv/data/dumps/postgres-$(date +%F).sql
docker exec mysql-db mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases > /srv/data/dumps/mysql-$(date +%F).sql
find /srv/data/dumps -mtime +3 -delete
Duplicati умеет запускать внешние команды до и после задачи через Options → Run script before — укажите путь к скрипту внутри контейнера (потребуется примонтировать сам скрипт и дать доступ к Docker socket, либо проще — запускать дамп отдельным cron-заданием на хосте, которое кладёт файлы в /srv/data/dumps, а Duplicati просто подхватывает готовые дампы как часть источника).
Для сравнения с более узким инструментом — если бэкап volume'ов это единственная задача и веб-интерфейс не нужен, короче и предсказуемее решение через docker run --rm -v и tar, разобранное в статье про бэкап Docker volume и типичные ошибки. Duplicati оправдан, когда источников несколько, нужно расписание и уведомления, а не разовый скрипт.
Шифрование и хранение секретов
Duplicati шифрует архивы AES-256 (встроенная реализация) или GPG (внешним бинарником, если он есть в образе). Три вещи, которые часто упускают:
- Пароль шифрования архива не совпадает с паролем веб-интерфейса и не хранится нигде, кроме зашифрованной локальной базы Duplicati. Потеряли — потеряли доступ к данным в хранилище, даже если файлы физически целы. Экспортируйте конфигурацию задачи (Export → File) сразу после настройки и держите копию отдельно от сервера.
SETTINGS_ENCRYPTION_KEYзащищает саму базу Duplicati с сохранёнными паролями бэкендов. Без него при переносе/configна новый сервер конфигурация не расшифруется.- Для облачных бэкендов (S3, B2) используйте отдельный ключ доступа с правами только на запись в конкретный бакет — если сервер скомпрометируют, злоумышленник не сможет прочитать или удалить старые бэкапы через тот же ключ.
Мониторинг, уведомления и проверка восстановления
Бэкап, который никто не проверял на восстановление, не бэкап, а надежда. В Duplicati:
- Settings → Notifications — email (через SMTP) или webhook (Telegram, Slack, любой HTTP-эндпоинт) при успехе/ошибке задачи;
- в списке задач цветной статус показывает последний результат — красный требует внимания сразу, не раз в квартал;
- раз в месяц стоит вручную запускать Restore во временную папку и сверять несколько файлов — это единственный способ убедиться, что архив реально читается, а не просто «задача завершилась успешно».
Если нужны внешние проверки доступности самой задачи по расписанию (например, что бэкап вообще запустился, а не просто не упал), удобно завести отдельный healthcheck-пинг из скрипта, аналогично тому, как это описано для cron-задач в целом.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Duplicati подходит для бэкапа большой базы данных (100+ ГБ)?
Технически да, но инкрементальный алгоритм на файловом уровне не заменяет транзакционно-согласованный дамп СУБД. Для больших баз лучше делать pg_dump/mysqldump в файл, а Duplicati уже бэкапить сам дамп — так снимок гарантированно консистентен.
Что будет с бэкапами, если сервер полностью выйдет из строя?
Если хранилище внешнее (S3, SFTP на другом сервере, WebDAV) — данные не пострадают, восстанавливать нужно будет на новом сервере через экспортированный файл конфигурации задачи. Если бэкапы лежат в /backups на том же диске — вы потеряете и данные, и их копию одновременно, это не резервное копирование, а иллюзия.
Можно ли обойтись без reverse proxy и просто открыть порт 8200 наружу?
Можно, но не стоит: встроенная аутентификация Duplicati не рассчитана на прямой доступ из интернета без TLS — пароль веб-интерфейса при HTTP передаётся в открытом виде. SSH-туннель для разового доступа или proxy с TLS для постоянного — минимальный разумный вариант.
Duplicati поддерживает несколько независимых задач бэкапа на одном сервере?
Да, в одном контейнере можно настроить сколько угодно задач с разными источниками, расписаниями и назначениями — это встроенный сценарий, отдельные контейнеры не нужны.
Как перенести настроенные задачи на другой сервер?
Экспортируйте каждую задачу в JSON через Export, на новом сервере поднимите тот же compose-файл и импортируйте файлы через Add backup → Import from file. Пароли шифрования архивов нужно ввести заново, если они не сохранены в экспортированном файле.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →