chore: update project documentation, audit reports, and initialize IDE configuration files
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

This commit is contained in:
Ho Ngoc Hai
2026-04-19 03:12:54 +07:00
parent 3be106074d
commit 11f2bf26e6
101 changed files with 21312 additions and 20672 deletions

View File

@@ -1,98 +1,98 @@
# Backup & Disaster Recovery
# Sao Lưu & Khôi Phục Thảm Họa
## RTO / RPO Targets
## Mục Tiêu RTO / RPO
| Metric | Target | Notes |
|--------|--------|-------|
| **RPO** (Recovery Point Objective) | ≤ 24 hours | Daily backups at 02:00 UTC; worst case is a full day of data loss |
| **RTO** (Recovery Time Objective) | ≤ 30 minutes | Restore from local volume backup; longer if retrieving from off-site |
| 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 |
> To reduce RPO further, consider WAL archiving for PostgreSQL (continuous point-in-time recovery) and more frequent backup schedules.
> Để 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.
---
## PostgreSQL Backup
## Sao Lưu PostgreSQL
### Overview
### Tổng quan
Automated daily PostgreSQL backups run inside the `pg-backup` Docker container using `pg_dump` with custom format compression. Backups are stored in the `pg_backups` Docker volume.
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`.
## Backup Configuration
## Cấu Hình Sao Lưu
| Setting | Default | Environment Variable |
|---------|---------|---------------------|
| Schedule | Daily at 02:00 UTC | Cron in `pg-backup` service |
| Retention | 7 days | `BACKUP_RETENTION_DAYS` |
| Format | Custom (`pg_dump --format=custom`) | — |
| Compression | Level 6 | — |
| Storage | `pg_backups` Docker volume | — |
| 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` | — |
## Listing Backups
## Liệt Kê Các Bản Sao Lưu
```bash
docker exec goodgo-pg-backup ls -lh /backups/
```
## Manual Backup
## Sao Lưu Thủ Công
```bash
docker exec goodgo-pg-backup /scripts/pg-backup.sh
```
## Restore Procedure
## Quy Trình Khôi Phục
### 1. Identify the backup to restore
### 1. Xác định bản sao lưu cần khôi phục
```bash
docker exec goodgo-pg-backup ls -lht /backups/
```
### 2. Stop application services
### 2. Dừng các service ứng dụng
```bash
docker compose stop ai-services
# Stop any NestJS API processes
```
### 3. Run restore
### 3. Chạy lệnh khôi phục
```bash
docker exec -it goodgo-pg-backup /scripts/pg-restore.sh /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz
```
The restore script will:
- Terminate active database connections
- Drop and recreate the database
- Restore from the selected backup
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. Verify restore
### 4. Xác minh khôi phục
```bash
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. Run Prisma migrations (if needed)
### 5. Chạy migration Prisma (nếu cần)
```bash
pnpm prisma migrate deploy
```
### 6. Restart services
### 6. Khởi động lại các service
```bash
docker compose up -d
```
## Backup Verification
## Xác Minh Bản Sao Lưu
Check the backup log:
Kiểm tra log sao lưu:
```bash
docker exec goodgo-pg-backup cat /var/log/pg-backup.log
```
Verify backup integrity without restoring:
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:
```bash
docker exec goodgo-pg-backup pg_restore --list /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz
@@ -100,11 +100,11 @@ docker exec goodgo-pg-backup pg_restore --list /backups/goodgo_YYYYMMDD_HHMMSS.s
---
## Redis Backup & Restore
## Sao Lưu & Khôi Phục Redis
Redis is configured with AOF persistence (`--appendonly yes`). Data is stored in the `redis_data` Docker volume.
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`.
### Manual Snapshot
### Snapshot Thủ Công
```bash
# Trigger an RDB snapshot
@@ -114,7 +114,7 @@ docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" BGSAVE
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" LASTSAVE
```
### Backup the Volume
### Sao Lưu Volume
```bash
# Stop Redis to ensure consistent snapshot
@@ -127,7 +127,7 @@ docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup
docker compose start redis
```
### Restore Redis
### Khôi Phục Redis
```bash
docker compose stop redis
@@ -139,15 +139,15 @@ docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup
docker compose start redis
```
> **Note:** Redis is used as a cache with `allkeys-lru` eviction. Full data loss is non-critical — the API will repopulate cache entries on demand. Restore is only necessary if session data or queue state must be preserved.
> **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.
---
## Typesense Backup & Restore
## Sao Lưu & Khôi Phục Typesense
Typesense data is stored in the `typesense_data` Docker volume.
Dữ liệu Typesense được lưu trữ trong Docker volume `typesense_data`.
### Create Snapshot
### Tạo Snapshot
```bash
# Typesense built-in snapshot API
@@ -155,7 +155,7 @@ curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/operations/snapshot?snapshot_path=/data/snapshots/$(date +%Y%m%d)"
```
### Backup the Volume
### Sao Lưu Volume
```bash
docker compose stop typesense
@@ -166,7 +166,7 @@ docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/ba
docker compose start typesense
```
### Restore Typesense
### Khôi Phục Typesense
```bash
docker compose stop typesense
@@ -177,9 +177,9 @@ docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/ba
docker compose start typesense
```
### Rebuild from Source
### Xây Dựng Lại Từ Nguồn
If backup is unavailable, Typesense can be rebuilt by re-indexing from PostgreSQL:
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:
```bash
# After Typesense restarts with empty data:
@@ -188,63 +188,63 @@ pnpm run typesense:reindex
---
## Disaster Recovery Runbook
## Sổ Tay Khôi Phục Thảm Họa
### Scenario 1: PostgreSQL Failure (container crash or data corruption)
### Kịch bản 1: Lỗi PostgreSQL (container crash hoặc hỏng dữ liệu)
1. **Assess:** `docker logs goodgo-postgres`check for corruption or OOM
2. **Stop services:** `docker compose stop api ai-services`
3. **Attempt restart:** `docker compose restart postgres`
4. If restart fails (data corruption):
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`
- Remove volume: `docker volume rm goodgo-platform-ai_postgres_data`
- Recreate: `docker compose up -d postgres`
- Restore from backup: `docker exec goodgo-pg-backup /scripts/pg-restore.sh /backups/<latest>.sql.gz`
- Verify: `docker exec goodgo-postgres psql -U goodgo -d goodgo -c '\dt'`
- Run migrations: `pnpm prisma migrate deploy`
5. **Restart services:** `docker compose up -d`
6. **Verify:** Check API health at `http://localhost:3000/health`
- 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`
**Expected RTO:** ~15 minutes (local backup), ~30 minutes (off-site backup)
**RTO dự kiến:** ~15 phút (sao lưu cục bộ), ~30 phút (sao lưu ngoài site)
### Scenario 2: Service Crash (API, AI-services, or Web)
### Kịch bản 2: Service Bị Crash (API, AI-services hoặc Web)
1. **Check logs:** `docker compose logs --tail=100 <service>`
2. **Restart service:** `docker compose restart <service>`
3. If crash loops:
- Check resource limits: `docker stats`
- Check environment variables: `docker compose config`
- Roll back to previous image tag if recent deployment caused the issue
4. **Verify:** Check health endpoints
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
**Expected RTO:** ~5 minutes
**RTO dự kiến:** ~5 phút
### Scenario 3: Full Host Failure
### Kịch bản 3: Hỏng Toàn Bộ Máy Chủ
1. Provision new host with Docker + Docker Compose
2. Clone the repo and set up `.env` from secrets manager
3. Pull images: `docker compose pull`
4. Restore PostgreSQL backup from off-site storage
5. Start all services: `docker compose up -d`
6. Trigger Typesense reindex: `pnpm run typesense:reindex`
7. Verify all health endpoints
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
**Expected RTO:** ~60 minutes (depends on backup transfer speed)
**RTO dự kiến:** ~60 phút (phụ thuộc vào tốc độ truyền bản sao lưu)
### Scenario 4: Data Corruption (application-level)
### Kịch bản 4: Hỏng Dữ Liệu (cấp độ ứng dụng)
1. Identify the scope: which tables/records are affected
2. If limited: restore specific tables using `pg_restore --table=<name>`
3. If widespread: full restore from last known good backup
4. Invalidate Redis cache: `docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" FLUSHALL`
5. Reindex Typesense: `pnpm run typesense:reindex`
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`
---
## Log Aggregation
## Tổng Hợp Log
Logs are aggregated via Loki + Promtail and viewable in Grafana:
Log được tổng hợp qua Loki + Promtail và có thể xem trong Grafana:
- **Grafana**: http://localhost:3002 (dashboard: "GoodGo - Logs")
- **Loki**: http://localhost:3100
- **Log retention**: 15 days (configured in `monitoring/loki/loki-config.yml`)
- **Thời gian lưu log**: 15 ngày (được cấu hình trong `monitoring/loki/loki-config.yml`)