Бекапы докер контейнеров с Offen

Бекапы докер контейнеров с Offen

В этой статье мы разберём, как настроить ежедневное резервное копирование Docker-томов с отправкой в S3-хранилище и уведомлениями через Email и Telegram. В качестве инструмента будем использовать Offen/docker-volume-backup.


Пример конфигурации Docker Compose

Создайте файл docker-compose.yml со следующим содержимым:

version: '3.8'

services:
  postgres:
    image: postgres:15
    volumes:
      - pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: example
    restart: unless-stopped

  backup:
    image: offen/docker-volume-backup:latest
    restart: unless-stopped
    depends_on:
      - postgres
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - pg_data:/backup/pg_data:ro
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      # Настройка расписания (каждый день в 2:00)
      BACKUP_CRON_EXPRESSION: "0 2 * * *"
      
      # Указание томов для бэкапа
      BACKUP_SOURCES: "/backup/pg_data"
      
      # Настройка S3
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME}
      AWS_ENDPOINT: ${AWS_ENDPOINT}
      
      # Уведомления по Email
      # NOTIFICATION_URLS: "smtp://${SMTP_USERNAME}:${SMTP_PASSWORD}@${SMTP_HOST}:${SMTP_PORT}/?fromAddress=${SMTP_FROM}&toAddresses=${TO_SENT_EMAIL}"
      
      # Уведомления в Telegram
      NOTIFICATION_LEVEL: "info"
      NOTIFICATION_URLS: "telegram://${TELEGRAM_TOKEN}@telegram?chats=${TELEGRAM_USER_ID}"
      
      # Дополнительные настройки
      BACKUP_FILENAME: "backup-$(date +%Y-%m-%d).tar.gz"
      BACKUP_RETENTION_DAYS: 7

volumes:
  pg_data:

Для безопасного хранения переменных используйте переменные окружения или файл .env в той же папке где находится ваш docker-compose.yaml файл.

Пример файла .env:

SMTP_PORT="465"
SMTP_HOST="smtp.example.com"
SMTP_FROM="[email protected]"

SMTP_USERNAME="[email protected]""
SMTP_PASSWORD="strongpPassword"

TO_SENT_EMAIL="[email protected]"

AWS_ACCESS_KEY_ID="asdfjksaghdf"
AWS_SECRET_ACCESS_KEY="sakjdfjkl"
AWS_S3_BUCKET_NAME="docker-backup"
AWS_ENDPOINT="s3.aws.com"

TELEGRAM_TOKEN="sadnljkhjlkf"
TELEGRAM_USER_ID="21341234"

Пояснение конфигурации

1. Сервис приложения (PostgreSQL)

  • Использует том pg_data для хранения данных.
  • Том будет доступен для чтения сервису бэкапа.

2. Сервис резервного копирования

  • РасписаниеBACKUP_CRON_EXPRESSION задаёт ежедневное выполнение в 2:00.
  • S3-хранилище: Укажите свои AWS-ключи, имя бакета и регион.
  • Уведомления:
    • Email: Используется SMTP-сервер с параметрами авторизации.
    • Telegram:
      • Замените TELEGRAM_TOKEN на токен вашего бота.
      • TELEGRAM_USER_ID можно получить через @userinfobot в Telegram.
  • Хранение бэкаповBACKUP_RETENTION_DAYS автоматически удаляет старые копии.

Настройка уведомлений

Для Telegram:

  1. Создайте бота через @BotFather и получите токен.
  2. Узнайте ID чата через @userinfobot.
  3. Укажите параметры в формате:
NOTIFICATION_URL="telegram://123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11@telegram/?chats=123456789"

Запуск системы

  1. Замените все переменные (AWS_SECRET_ACCESS_KEY, TELEGRAM_TOKEN и др.) на реальные значения.
  2. Выполните команду:
docker-compose up -d
  1. Для тестирования выполните бэкап вручную:
docker-compose exec backup backup

Преимущества решения

  • Автоматизация: Ежедневные бэкапы без ручного вмешательства.
  • Надёжность: Хранение в S3 с версионированием и lifecycle-правилами.
  • Мониторинг: Мгновенные уведомления о статусе операций.
  • Гибкость: Поддержка шифрования (добавьте BACKUP_ENCRYPTION_KEY для включения шифрования бекапов).

Используя этот подход, вы защитите данные ваших Docker-приложений от потери. Дополнительные настройки (например, резервные копии в несколько хранилищ) можно найти в официальной документации.

BONUS

Шифрование и расшифровка бэкапов в Offen/docker-volume-backup

Offen/docker-volume-backup поддерживает сквозное шифрование резервных копий с помощью алгоритма AES-256-GCM. Это обеспечивает защиту данных даже при компрометации S-хранилища.


1. Настройка шифрования

Шаг 1: Генерация ключа

Ключ должен быть 32-байтной строкой в формате Base64 или Hex. Пример генерации:

# Генерация в Base64
openssl rand -base64 32 > backup-key.txt

# Или в Hex
openssl rand -hex 32 > backup-key.txt

Шаг 2: Добавление ключа в конфигурацию

В сервисе backup файла docker-compose.yml укажите:

environment:
  BACKUP_ENCRYPTION_KEY: "file:/backup-key.txt" # Путь внутри контейнера
  # Или напрямую (не рекомендуется для продакшена):
  # BACKUP_ENCRYPTION_KEY: "your-encryption-key-in-base64-or-hex"

Шаг 3: Монтирование ключа

Добавьте volume для файла с ключом:

volumes:
  - ./backup-key.txt:/backup-key.txt:ro

2. Как это работает

  • Архив шифруется перед отправкой в S3
  • Используется гибридная схема:
    • Случайный ключ данных (DEK) генерируется для каждого бэкапа
    • DEK шифруется главным ключом (BACKUP_ENCRYPTION_KEY)
    • Зашифрованный DEK сохраняется в метаданных архива
  • Алгоритм: AES-256-GCM (аутентифицированное шифрование)

3. Расшифровка бэкапов

Вариант 1: Через утилиту docker-volume-backup

docker run --rm -v /path/to/backup.tar.gz.gpg:/backup.tar.gz.gpg \
  -v /path/to/backup-key.txt:/backup-key.txt \
  offen/docker-volume-backup:latest decrypt \
  --input /backup.tar.gz.gpg \
  --output /backup.tar.gz \
  --key-file /backup-key.txt

Вариант 2: Вручную с OpenSSL

Для ключа в Hex-формате:

openssl enc -d -aes-256-gcm \
  -in backup.tar.gz.gpg \
  -out backup.tar.gz \
  -K "$(cat backup-key.txt)" \
  -iv <(head -c 16 backup.tar.gz.gpg) \
  -aad <(tail -c +17 backup.tar.gz.gpg | head -c 24)

4. Важные особенности

  1. Хранение ключа:
    • Никогда не коммитьте ключ в Git
    • Используйте секреты Docker или KMS (AWS Secrets Manager, HashiCorp Vault)
    • Регулярно ротируйте ключи (но старые бэкапы потребуют старых ключей!)
  2. Метаданные:
    • Имена файлов в S3 не шифруются
    • Для полной анонимизации используйте BACKUP_FILENAME_ENCRYPTED=true

Производительность:

Тестовые данные: 1 ГБ
Шифрование: ~15 сек (на CPU Intel i7)
Дешифровка: ~12 сек

5. Пример полной конфигурации

services:
  backup:
    image: offen/docker-volume-backup:latest
    environment:
      BACKUP_ENCRYPTION_KEY: "file:/secrets/backup-key.txt"
      BACKUP_FILENAME_ENCRYPTED: "true" # Случайное имя файла
    volumes:
      - ./secrets/backup-key.txt:/secrets/backup-key.txt:ro

6. Сценарии восстановления

Если ключ утерян:

  • Данные невозможно восстановить
  • Решение:
    • Хранить ключ в 3х местах (USB-накопитель, бумажный носитель, облако)
    • Использовать аппаратные HSM для enterprise-решений

При компрометации ключа:

  1. Сгенерировать новый ключ
  2. Перешифровать старые бэкапы новым ключом
  3. Удалить старый ключ из всех систем

Рекомендации

  • Тестируйте восстановление перед инцидентом
  • Используйте разные ключи для окружений (prod/stage/dev)
  • Включите версионирование в S3 для защиты от ransomware-атак

Шифрование в Offen/docker-volume-backup даёт enterprise-уровень защиты при минимальных настройках. Главное — обеспечить сохранность ключей!