Docker backup and restore production architecture

Backup và Restore Docker Volume với Restic, Rclone, Cron

Backup & Restore Docker Volumes trong Production: Chiến lược an toàn với Restic + Rclone + Cron

Docker giúp deploy nhanh, nhưng phần dữ liệu persistent mới là thứ quyết định sống còn trong production. Mất container có thể recreate trong vài giây; mất dữ liệu trong volume có thể làm downtime hàng giờ hoặc mất dữ liệu vĩnh viễn. Backup Docker Volumes trên Linux với restic: chiến lược an toàn và restore drill

Bài này đi thẳng vào bài toán thực tế: thiết kế một pipeline backup/restore Docker volumes an toàn, có mã hóa, có kiểm tra integrity, có retention policy, chạy tự động bằng cron, và test restore định kỳ.

Vì sao backup volume khác với backup source code?

Source code đã nằm trong Git, image có thể build lại từ Dockerfile. Nhưng dữ liệu runtime trong volume (database files, uploads, queue state, cache quan trọng, config generated runtime) thường không có bản sao thứ hai nếu bạn không backup đúng cách.

Các sai lầm phổ biến:

  • Chỉ backup container image, quên backup volume
  • Backup bằng cách copy “live data” không quiesce service → snapshot không consistent
  • Không test restore
  • Không có retention rõ ràng
  • Backup local cùng máy production (single point of failure)

Khi nào cần dùng chiến lược này?

Pipeline trong bài phù hợp khi bạn có:

  • 1 hoặc nhiều host Linux chạy Docker
  • Workload như MariaDB/MySQL, PostgreSQL, Redis persistence, WordPress uploads, app state
  • Nhu cầu backup offsite (S3-compatible, Backblaze B2, Wasabi, MinIO remote)
  • Muốn kiểm soát bằng CLI, dễ audit, dễ automate

Kiến trúc backup đề xuất

Mục tiêu:

  1. Export dữ liệu volume thành snapshot tạm
  2. Backup snapshot bằng restic (encrypted + deduplicated)
  3. Push repo đến remote qua rclone (hoặc restic backend trực tiếp)
  4. Verify backup và restore test định kỳ

Luồng chuẩn:

  1. Quiesce ứng dụng (hoặc DB dump logical nếu là database)
  2. Tar volume data vào staging
  3. restic backup
  4. restic forget --prune theo retention
  5. restic check
  6. Cleanup staging

Prerequisites

  • Ubuntu/Debian/CentOS có Docker Engine
  • Cài restic, rclone, jq, gzip
  • Có bucket/object storage và credentials
  • Có biến môi trường bảo mật:

RESTIC_REPOSITORY

RESTIC_PASSWORD

AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (nếu backend S3)

Ví dụ cài đặt trên Ubuntu:


sudo apt update
sudo apt install -y restic rclone jq gzip

Xác định volume quan trọng trước khi backup

Liệt kê volume:


docker volume ls

Inspect chi tiết:


docker volume inspect wordpress_data mysql_data redis_data

Bạn nên phân loại:

  • Tier 1 (critical): DB data, user uploads, billing records
  • Tier 2 (important): app config runtime
  • Tier 3 (rebuildable): cache không cần backup

Không backup tràn lan mọi volume nếu không cần, để tiết kiệm storage và giảm thời gian restore.

Script backup mẫu (production-friendly)

Dưới đây là script mẫu backup-docker-volumes.sh:


#!/usr/bin/env bash
set -euo pipefail

DATE="$(date +%F-%H%M%S)"
HOST="$(hostname -s)"
WORKDIR="/var/backups/docker-volumes/${DATE}"
LOGFILE="/var/log/docker-volume-backup.log"

VOLUMES=("wordpress_data" "mysql_data" "redis_data")

# Ensure env exists
: "${RESTIC_REPOSITORY:?Missing RESTIC_REPOSITORY}"
: "${RESTIC_PASSWORD:?Missing RESTIC_PASSWORD}"

mkdir -p "$WORKDIR"

log() {
  echo "[$(date '+%F %T')] $*" | tee -a "$LOGFILE"
}

cleanup() {
  rm -rf "$WORKDIR"
}
trap cleanup EXIT

log "=== Backup start: $DATE ==="

# Optional: quiesce app (example)
# docker compose -f /opt/stack/docker-compose.yml pause app

for vol in "${VOLUMES[@]}"; do
  ARCHIVE="${WORKDIR}/${vol}.tar.gz"
  log "Archiving volume: $vol"

  docker run --rm \
    -v "${vol}:/volume:ro" \
    -v "${WORKDIR}:/backup" \
    alpine:3.20 \
    sh -c "tar czf /backup/${vol}.tar.gz -C /volume ."
done

# Optional: DB logical dump (recommended for MySQL/PostgreSQL)
# mysqldump --single-transaction --quick ... > "${WORKDIR}/mysql-logical.sql"

log "Running restic backup"
restic backup "$WORKDIR" --tag "docker-volumes" --tag "$HOST"

log "Applying retention"
restic forget --prune \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --tag docker-volumes

log "Checking repository"
restic check --read-data-subset=5%

# Optional: unquiesce app
# docker compose -f /opt/stack/docker-compose.yml unpause app

log "=== Backup completed successfully ==="

Vì sao dùng restic?

Restic phù hợp cho production nhỏ-vừa vì:

  • Encrypt mặc định phía client
  • Dedup theo block giúp tiết kiệm storage
  • Snapshot theo thời gian, restore linh hoạt
  • Có integrity check
  • Hỗ trợ nhiều backend: local, S3, B2, SFTP, MinIO

Lên lịch tự động bằng cron (07:00–22:00)

Yêu cầu của bạn là chỉ chạy trong khung 07:00–22:00. Với backup, khung tối ưu thường là giờ ít traffic, ví dụ 20:30.


30 20 * * * /usr/local/bin/backup-docker-volumes.sh >> /var/log/docker-volume-backup.log 2>&1

Nếu cần chạy nhiều lần/ngày nhưng vẫn trong khung cho phép:


0 8,14,20 * * * /usr/local/bin/backup-docker-volumes.sh >> /var/log/docker-volume-backup.log 2>&1

Restore quy trình chuẩn (không panic)

Nguyên tắc: restore vào môi trường staging trước, xác thực rồi mới áp dụng production.

Bước 1: Liệt kê snapshots


restic snapshots --tag docker-volumes

Bước 2: Restore snapshot


mkdir -p /tmp/restore-test
restic restore <SNAPSHOT_ID> --target /tmp/restore-test

Bước 3: Restore lại volume cụ thể


# Ví dụ restore wordpress_data
mkdir -p /tmp/restore-vol
cd /tmp/restore-test/var/backups/docker-volumes/<DATE>
tar xzf wordpress_data.tar.gz -C /tmp/restore-vol

# overwrite vào Docker volume
docker run --rm \
  -v wordpress_data:/volume \
  -v /tmp/restore-vol:/restore \
  alpine:3.20 sh -c "rm -rf /volume/* && cp -a /restore/. /volume/"

Bước 4: Verify app

  • Service start bình thường
  • Health check pass
  • Dữ liệu mới nhất đúng kỳ vọng
  • Log không có lỗi migration/corruption

Checklist production backup

  • [ ] Có inventory volume critical
  • [ ] Có backup schedule rõ ràng
  • [ ] Có offsite storage
  • [ ] Có encryption at rest + in transit
  • [ ] Có retention policy (daily/weekly/monthly)
  • [ ] Có restore drill hàng tháng
  • [ ] Có alert khi backup fail
  • [ ] Có tài liệu runbook cho on-call

Troubleshooting thường gặp

1) permission denied khi tar volume

Nguyên nhân: UID/GID trong container không tương thích khi mount.

Cách xử lý:

  • Dùng container backup chạy root (mặc định trong alpine)
  • Đảm bảo mount read-only cho source
  • Nếu volume dùng SELinux, kiểm tra context

2) Backup thành công nhưng restore app lỗi data corruption

Nguyên nhân: backup file-level khi DB đang ghi dữ liệu.

Cách xử lý:

  • Ưu tiên logical dump cho DB (mysqldump/pg_dump)
  • Hoặc stop writer tạm thời trước snapshot
  • Với PostgreSQL, cân nhắc WAL archiving cho RPO thấp

3) restic check fail hoặc có blob missing

Nguyên nhân: storage backend lỗi, đồng bộ nửa chừng, thao tác xóa sai.

Cách xử lý:

  • Chạy restic check --read-data
  • Kiểm tra object storage lifecycle policy
  • Không xóa file thủ công trong repo restic

4) Storage cost tăng nhanh

Nguyên nhân: retention quá dài hoặc backup nhiều dữ liệu tạm.

Cách xử lý:

  • Loại trừ file không cần (cache, tmp)
  • Tối ưu retention
  • Tách policy theo loại dữ liệu

Security notes cho backup

  • Không hardcode secrets trong script
  • Dùng /etc/restic/env với permission 600
  • Rotate access key định kỳ
  • Bật versioning ở bucket
  • Giới hạn IAM policy theo principle of least privilege

Ví dụ nạp env an toàn:


set -a
source /etc/restic/env
set +a

Monitoring & Alerting

Không có alert thì backup fail cũng không ai biết.

Bạn nên gửi alert khi:

  • Exit code script != 0
  • Backup duration vượt ngưỡng
  • Không có snapshot mới trong 24h

Ví dụ đơn giản dùng webhook (Slack/Telegram/custom endpoint) sau mỗi lần backup.

FAQ

Backup Docker volume mỗi ngày có đủ không?

Tùy RPO. Nếu chấp nhận mất tối đa 24h dữ liệu thì daily có thể đủ. Với hệ thống transactional, nên tăng tần suất (4-6h) hoặc kết hợp database-native backup.

Có nên chỉ dùng docker run --rm -v volume ... tar mà không restic?

Có thể dùng cho môi trường nhỏ, nhưng restic giúp encryption, dedup, snapshot management và restore tốt hơn nhiều.

Bind mount có backup giống volume không?

Có thể backup trực tiếp filesystem host, nhưng cần chú ý consistency như volume. Điểm khác là bind mount phụ thuộc cấu trúc host.

Có cần test restore định kỳ không?

Bắt buộc. Backup chưa test restore thì chưa được xem là backup đáng tin cậy.

Kết luận

Một hệ Docker production đáng tin không chỉ cần docker compose up -d, mà cần chiến lược backup/restore có kỷ luật:

  • Backup đúng dữ liệu quan trọng
  • Encrypt + offsite + retention
  • Test restore định kỳ
  • Có runbook và alert

Nếu làm đúng 4 điểm trên, khi sự cố xảy ra bạn sẽ chuyển từ trạng thái panic sang trạng thái “có quy trình, có dữ liệu, có thời gian phục hồi rõ ràng”.

Meta title (<=60): Backup Docker Volumes Production: Restic + Cron

Meta description (<=155): Hướng dẫn backup và restore Docker volumes trong production với Restic, retention, cron automation, troubleshooting và checklist bảo mật.

Slug: docker-volume-backup-restore-production-restic-cron

Excerpt (150-160): Hướng dẫn chuyên sâu backup/restore Docker volumes cho production với Restic, cron, retention policy, integrity check và checklist khắc phục sự cố.

Đề xuất internal links (techsysad):

  1. Bài về Docker Compose best practices
  2. Bài về hardening Linux server
  3. Bài về monitoring với Prometheus/Grafana

Leave a Comment

Your email address will not be published. Required fields are marked *