Files
goodgo-platform/docs/backup-restore.md
Ho Ngoc Hai 11f2bf26e6
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
chore: update project documentation, audit reports, and initialize IDE configuration files
2026-04-19 03:12:54 +07:00

8.1 KiB

Sao Lưu & Khôi Phục Thảm Họa

Mục Tiêu RTO / RPO

Chỉ số Mục tiêu Ghi chú
RPO (Mục tiêu Điểm Khôi phục) ≤ 24 giờ Sao lưu hàng ngày lúc 02:00 UTC; trường hợp xấu nhất là mất toàn bộ dữ liệu trong một ngày
RTO (Mục tiêu Thời gian Khôi phục) ≤ 30 phút Khôi phục từ bản sao lưu volume cục bộ; lâu hơn nếu lấy từ nơi lưu trữ ngoài site

Để giảm RPO hơn nữa, hãy xem xét lưu trữ WAL cho PostgreSQL (khôi phục liên tục theo thời gian thực) và lên lịch sao lưu thường xuyên hơn.


Sao Lưu PostgreSQL

Tổng quan

Sao lưu PostgreSQL tự động hàng ngày chạy bên trong Docker container pg-backup bằng pg_dump với nén định dạng tùy chỉnh. Các bản sao lưu được lưu trữ trong Docker volume pg_backups.

Cấu Hình Sao Lưu

Thiết lập Mặc định Biến môi trường
Lịch Hàng ngày lúc 02:00 UTC Cron trong service pg-backup
Thời gian lưu 7 ngày BACKUP_RETENTION_DAYS
Định dạng Tùy chỉnh (pg_dump --format=custom)
Nén Mức 6
Lưu trữ Docker volume pg_backups

Liệt Kê Các Bản Sao Lưu

docker exec goodgo-pg-backup ls -lh /backups/

Sao Lưu Thủ Công

docker exec goodgo-pg-backup /scripts/pg-backup.sh

Quy Trình Khôi Phục

1. Xác định bản sao lưu cần khôi phục

docker exec goodgo-pg-backup ls -lht /backups/

2. Dừng các service ứng dụng

docker compose stop ai-services
# Stop any NestJS API processes

3. Chạy lệnh khôi phục

docker exec -it goodgo-pg-backup /scripts/pg-restore.sh /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz

Script khôi phục sẽ:

  • Chấm dứt các kết nối cơ sở dữ liệu đang hoạt động
  • Xóa và tạo lại cơ sở dữ liệu
  • Khôi phục từ bản sao lưu đã chọn

4. Xác minh khôi phục

docker exec goodgo-postgres psql -U goodgo -d goodgo -c '\dt'
docker exec goodgo-postgres psql -U goodgo -d goodgo -c 'SELECT count(*) FROM "User";'

5. Chạy migration Prisma (nếu cần)

pnpm prisma migrate deploy

6. Khởi động lại các service

docker compose up -d

Xác Minh Bản Sao Lưu

Kiểm tra log sao lưu:

docker exec goodgo-pg-backup cat /var/log/pg-backup.log

Xác minh tính toàn vẹn của bản sao lưu mà không cần khôi phục:

docker exec goodgo-pg-backup pg_restore --list /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz

Sao Lưu & Khôi Phục Redis

Redis được cấu hình với tính năng bền vững AOF (--appendonly yes). Dữ liệu được lưu trong Docker volume redis_data.

Snapshot Thủ Công

# Trigger an RDB snapshot
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" BGSAVE

# Wait for completion
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" LASTSAVE

Sao Lưu Volume

# Stop Redis to ensure consistent snapshot
docker compose stop redis

# Copy volume data to a backup location
docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup \
  alpine tar czf /backup/redis_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .

docker compose start redis

Khôi Phục Redis

docker compose stop redis

# Clear existing data and restore
docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup \
  alpine sh -c "rm -rf /data/* && tar xzf /backup/redis_YYYYMMDD_HHMMSS.tar.gz -C /data"

docker compose start redis

Lưu ý: Redis được dùng làm cache với chính sách loại bỏ allkeys-lru. Mất toàn bộ dữ liệu không nghiêm trọng — API sẽ tự động nạp lại các mục cache theo yêu cầu. Việc khôi phục chỉ cần thiết khi dữ liệu phiên hoặc trạng thái hàng đợi phải được giữ nguyên.


Sao Lưu & Khôi Phục Typesense

Dữ liệu Typesense được lưu trữ trong Docker volume typesense_data.

Tạo Snapshot

# Typesense built-in snapshot API
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
  "http://localhost:8108/operations/snapshot?snapshot_path=/data/snapshots/$(date +%Y%m%d)"

Sao Lưu Volume

docker compose stop typesense

docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/backup \
  alpine tar czf /backup/typesense_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .

docker compose start typesense

Khôi Phục Typesense

docker compose stop typesense

docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/backup \
  alpine sh -c "rm -rf /data/* && tar xzf /backup/typesense_YYYYMMDD_HHMMSS.tar.gz -C /data"

docker compose start typesense

Xây Dựng Lại Từ Nguồn

Nếu bản sao lưu không có sẵn, Typesense có thể được xây dựng lại bằng cách lập chỉ mục lại từ PostgreSQL:

# After Typesense restarts with empty data:
pnpm run typesense:reindex

Sổ Tay Khôi Phục Thảm Họa

Kịch bản 1: Lỗi PostgreSQL (container crash hoặc hỏng dữ liệu)

  1. Đánh giá: docker logs goodgo-postgres — kiểm tra tình trạng hỏng dữ liệu hoặc OOM
  2. Dừng service: docker compose stop api ai-services
  3. Thử khởi động lại: docker compose restart postgres
  4. Nếu khởi động lại thất bại (hỏng dữ liệu):
    • docker compose stop postgres
    • Xóa volume: docker volume rm goodgo-platform-ai_postgres_data
    • Tạo lại: docker compose up -d postgres
    • Khôi phục từ bản sao lưu: docker exec goodgo-pg-backup /scripts/pg-restore.sh /backups/<latest>.sql.gz
    • Xác minh: docker exec goodgo-postgres psql -U goodgo -d goodgo -c '\dt'
    • Chạy migration: pnpm prisma migrate deploy
  5. Khởi động lại các service: docker compose up -d
  6. Xác minh: Kiểm tra API health tại http://localhost:3000/health

RTO dự kiến: ~15 phút (sao lưu cục bộ), ~30 phút (sao lưu ngoài site)

Kịch bản 2: Service Bị Crash (API, AI-services hoặc Web)

  1. Kiểm tra log: docker compose logs --tail=100 <service>
  2. Khởi động lại service: docker compose restart <service>
  3. Nếu crash lặp lại:
    • Kiểm tra giới hạn tài nguyên: docker stats
    • Kiểm tra biến môi trường: docker compose config
    • Rollback về image tag trước nếu triển khai gần đây gây ra sự cố
  4. Xác minh: Kiểm tra các endpoint health

RTO dự kiến: ~5 phút

Kịch bản 3: Hỏng Toàn Bộ Máy Chủ

  1. Cung cấp máy chủ mới với Docker + Docker Compose
  2. Clone repo và thiết lập .env từ secrets manager
  3. Pull image: docker compose pull
  4. Khôi phục bản sao lưu PostgreSQL từ nơi lưu trữ ngoài site
  5. Khởi động tất cả service: docker compose up -d
  6. Kích hoạt lập chỉ mục lại Typesense: pnpm run typesense:reindex
  7. Xác minh tất cả endpoint health

RTO dự kiến: ~60 phút (phụ thuộc vào tốc độ truyền bản sao lưu)

Kịch bản 4: Hỏng Dữ Liệu (cấp độ ứng dụng)

  1. Xác định phạm vi: những bảng/bản ghi nào bị ảnh hưởng
  2. Nếu hạn chế: khôi phục các bảng cụ thể bằng pg_restore --table=<name>
  3. Nếu diện rộng: khôi phục toàn bộ từ bản sao lưu tốt cuối cùng được biết đến
  4. Xóa cache Redis: docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" FLUSHALL
  5. Lập chỉ mục lại Typesense: pnpm run typesense:reindex

Tổng Hợp Log

Log được tổng hợp qua Loki + Promtail và có thể xem trong Grafana: