Deploy Kopia trên Docker: Backup Mã Hóa Đầu Cuối, Chống Trùng Lặp cho HomeLab

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Chọn Công Cụ Backup Phù Hợp: Kopia vs. Các Lựa Chọn Khác

Sau vài năm chạy HomeLab, tôi đã thử qua đủ loại công cụ backup — bắt đầu với Duplicati (web UI khá tiện cho đến khi gặp lỗi hỏng database), rồi chuyển sang Restic (ổn định nhưng chỉ có CLI), và cuối cùng dừng lại ở Kopia. Lựa chọn phù hợp phụ thuộc vào mức độ bạn chịu được với terminal và liệu web UI có thực sự cần thiết cho workflow của bạn hay không.

Dưới đây là so sánh ba công cụ chính cho môi trường self-hosted:

  • Duplicati — Dễ cài đặt nhất, có web UI sẵn. Điểm trừ là lỗi hỏng SQLite nổi tiếng, thường xuất hiện sau các job chạy lâu hoặc bị ngắt giữa chừng — đặc biệt với những tác vụ chạy vài tiếng hoặc crash khi đang sync. Restore có thể thất bại hoàn toàn mà không có cảnh báo, bạn chỉ phát hiện khi thực sự cần đến dữ liệu. Với backup quan trọng, đây là điều không thể chấp nhận được.
  • Restic — Cực kỳ ổn định, deduplication tốt, được cộng đồng sysadmin tin dùng rộng rãi. Nhược điểm là chỉ có CLI thuần túy — không có web interface, không có scheduler tích hợp, không có server mode. Phù hợp cho setup dạng script, nhưng sẽ kém thoải mái khi bạn muốn theo dõi toàn bộ service trong HomeLab.
  • Kopia — Lựa chọn hiện đại kết hợp ưu điểm của cả hai: độ tin cậy và deduplication ngang tầm Restic, cộng thêm web UI đầy đủ và server mode. Chạy như một background service có thể truy cập qua trình duyệt hoặc CLI, hỗ trợ nhiều storage backend, và mã hóa toàn bộ dữ liệu ở phía client trước khi gửi đi.

Velero phù hợp nếu bạn đang dùng Kubernetes — backup snapshot ở cấp cluster, hoàn toàn khác danh mục so với backup thư mục thông thường.

Kopia: Điểm Mạnh và Hạn Chế

Điểm mạnh

  • Mã hóa đầu cuối (end-to-end encryption) — Toàn bộ dữ liệu được mã hóa phía client bằng AES-256-GCM trước khi đến đích lưu trữ. Backend không bao giờ thấy dữ liệu thuần. Điều này rất quan trọng khi bạn đẩy lên cloud storage mà bạn không hoàn toàn kiểm soát — dù tài khoản B2 bị xâm phạm, kẻ tấn công cũng chỉ thu được các blob đã mã hóa mà không thể đọc được.
  • Deduplication theo content-addressable — Kopia chia file thành các chunk có độ dài thay đổi và chỉ lưu mỗi chunk duy nhất một lần trong toàn bộ snapshot. Backup 100GB Docker volume với 60% dữ liệu trùng lặp theo thời gian? Bạn chỉ cần lưu khoảng 40GB. Hiệu quả này tích lũy dần sau nhiều tuần backup hàng ngày.
  • Nhiều backend trong một công cụ — Tương thích S3 (AWS, MinIO, Cloudflare R2), Backblaze B2, filesystem local, SFTP, WebDAV, Google Cloud Storage, Azure Blob. Không cần dùng công cụ riêng biệt cho từng đích lưu trữ.
  • Server mode với REST API và Web UI — Duyệt snapshot, kích hoạt backup, theo dõi tỷ lệ deduplication và quản lý policy mà không cần chạm vào terminal. Truy cập từ bất kỳ trình duyệt nào trong mạng local.
  • Nén dữ liệu — Nén zstd tùy chọn kết hợp với deduplication. Đặc biệt hiệu quả với log, file cấu hình và database dump.

Hạn chế

  • Phụ thuộc vào định dạng repository độc quyền — Định dạng repository của Kopia chỉ dùng được với Kopia. Bạn không thể mở repository Kopia bằng Restic hay bất kỳ công cụ nào khác. Muốn chuyển đổi có nghĩa là phải upload lại toàn bộ từ đầu.
  • Tài liệu còn thiếu cho các trường hợp nâng cao — Tài liệu chính thức đầy đủ cho các trường hợp phổ biến. Nhưng với việc tinh chỉnh retention nâng cao, lên lịch maintenance, hay phục hồi các trường hợp đặc biệt, bạn phải đào sâu vào GitHub issues và Discord.
  • Không có cảnh báo tích hợp — Kopia im lặng khi backup thất bại. Hãy tích hợp bên ngoài: một cron wrapper kiểm tra exit code và gửi cảnh báo qua Telegram hoặc email là đủ. Nếu không có, bạn sẽ không biết job nào bị lỗi cho đến khi mở UI.
  • Hệ sinh thái còn trẻ — Kopia đã sẵn sàng cho production nhưng mới hơn Restic. Khi có vấn đề bất thường, số lượng câu trả lời trên Stack Overflow và bài viết cộng đồng vẫn còn ít.

Setup Khuyến Nghị cho HomeLab

Setup này đã chạy trên HomeLab của tôi hơn một năm mà không có repository nào bị hỏng — Kopia trong Docker, backup lên NAS local và Backblaze B2 để có bản dự phòng offsite. Một số quyết định thiết kế giúp hệ thống ổn định:

  • Chạy Kopia ở server mode trong Docker — chỉ expose web UI trên cổng local, truy cập qua Tailscale hoặc SSH tunnel, tuyệt đối không public ra ngoài.
  • Dùng hai repository — một local (restore nhanh, không tốn phí egress) và một cloud (disaster recovery offsite). Mật khẩu khác nhau, cùng dữ liệu nguồn.
  • Mount Docker volume trực tiếp vào container Kopia dưới dạng nguồn read-only. Với database, hãy dump ra file trước rồi mới backup file dump đó.
  • Tách lịch backup và maintenance — backup chạy vài tiếng một lần, garbage collection và compaction chạy hàng tuần. Trộn lẫn hai việc gây overhead không cần thiết.

Deploy Kopia trên Docker: Từng Bước

1. Tạo File Docker Compose

Tạo thư mục làm việc và thêm docker-compose.yml:

version: "3.8"

services:
  kopia:
    image: kopia/kopia:latest
    container_name: kopia
    restart: unless-stopped
    ports:
      - "51515:51515"
    volumes:
      - /opt/kopia/config:/app/config
      - /opt/kopia/cache:/app/cache
      - /opt/kopia/logs:/app/logs
      - /mnt/nas/backups:/backups        # Thư mục lưu backup local
      - /opt/appdata:/data:ro            # Dữ liệu nguồn (chỉ đọc)
    environment:
      - KOPIA_PASSWORD=your-strong-repo-password
      - TZ=Asia/Tokyo
    command:
      - server
      - start
      - --insecure
      - --address=0.0.0.0:51515
      - --server-username=admin
      - --server-password=your-ui-password

Điều chỉnh /opt/appdata tùy theo vị trí Docker volume và dữ liệu ứng dụng của bạn. Cờ :ro trên mount nguồn là cố ý — Kopia chỉ đọc từ đó.

2. Khởi Tạo Repository

Khởi động container, sau đó khởi tạo repository backup:

# Khởi động container
docker compose up -d

# Khởi tạo repository trên filesystem local
docker exec -it kopia kopia repository create filesystem \
  --path=/backups/kopia-repo \
  --password=your-repo-password

# Hoặc khởi tạo repository Backblaze B2 cho offsite
docker exec -it kopia kopia repository create b2 \
  --bucket=your-bucket-name \
  --key-id=your-b2-key-id \
  --key=your-b2-application-key \
  --password=your-repo-password

Mật khẩu repository chính là khóa mã hóa cho toàn bộ dữ liệu của bạn. Hãy lưu nó ở nơi vật lý tách biệt với server — một entry trong password manager kết hợp bản in giấy để ở phòng khác là mức tối thiểu. Mất mật khẩu đồng nghĩa với mất trắng toàn bộ backup mãi mãi. Kopia không có backdoor.

3. Kết Nối Lại Sau Khi Rebuild Container

Nếu container bị tạo lại và mất trạng thái config, hãy kết nối lại với repository hiện có:

docker exec -it kopia kopia repository connect filesystem \
  --path=/backups/kopia-repo \
  --password=your-repo-password

4. Tạo Backup Policy

Policy xác định cài đặt retention và nén cho một đường dẫn nguồn:

# Đặt policy cho thư mục data
docker exec -it kopia kopia policy set /data \
  --compression=zstd \
  --keep-latest=10 \
  --keep-hourly=24 \
  --keep-daily=7 \
  --keep-weekly=4 \
  --keep-monthly=6

# Tạo snapshot đầu tiên thủ công
docker exec -it kopia kopia snapshot create /data

5. Lên Lịch Backup Tự Động

Kopia server mode không tự lên lịch snapshot. Một cron job đơn giản trên host xử lý việc này rất gọn:

# Chỉnh sửa crontab trên host
crontab -e

# Chạy backup mỗi 6 giờ
0 */6 * * * docker exec kopia kopia snapshot create /data >> /var/log/kopia-backup.log 2>&1

# Maintenance toàn bộ hàng tuần (dọn rác + compaction)
0 3 * * 0 docker exec kopia kopia maintenance run --full >> /var/log/kopia-maintenance.log 2>&1

6. Truy Cập Web UI

Mở http://your-homelab-ip:51515 trên trình duyệt và đăng nhập bằng thông tin đã khai báo trong file compose. Dashboard hiển thị lịch sử snapshot và mức sử dụng storage. Nhấp vào bất kỳ snapshot nào để duyệt từng file riêng lẻ — tiện cho việc kiểm tra nhanh một restore mà không cần tải hết dữ liệu về.

Hãy coi port 51515 là chỉ dùng nội bộ. Truy cập qua Tailscale, WireGuard, hoặc SSH tunnel (ssh -L 51515:localhost:51515 user@homelab-host) thay vì expose trực tiếp ra ngoài.

7. Phục Hồi từ Snapshot

# Liệt kê các snapshot hiện có
docker exec -it kopia kopia snapshot list /data

# Phục hồi snapshot theo ID
docker exec -it kopia kopia snapshot restore \
  k9a8b7c6d5e4f3a2b \
  /restore-target

# Mount snapshot để duyệt file mà không cần restore toàn bộ
docker exec -it kopia kopia mount k9a8b7c6d5e4f3a2b /mnt/kopia-mount

Một Số Điều Cần Biết Trước Khi Triển Khai

Hãy kiểm tra restore trước khi thực sự cần đến. Lên lịch drill hàng tháng — restore vào thư mục tạm và xác minh tính toàn vẹn của file. Hệ thống backup mà bạn chưa từng thực sự phục hồi chỉ là bảo vệ trên lý thuyết.

Đừng đánh giá tỷ lệ deduplication ngay từ ngày đầu. Repository mới sẽ hiển thị 0%. Sau một tuần backup hàng ngày trên dataset ổn định, 70–80% là mức bình thường — những con số này chỉ có ý nghĩa khi bạn đã tích lũy được một ít lịch sử.

Với database trong Docker (PostgreSQL, MySQL, MongoDB), luôn dump ra file trước khi backup. Kopia không hiểu cơ chế nội bộ của database — backup thư mục data khi database đang chạy có thể bắt dữ liệu ở trạng thái đang ghi dở. Hãy chạy pg_dump hoặc mysqldump vào thư mục mà Kopia theo dõi, rồi backup thư mục đó thay vào.

Share: