Migration Plan v2: Chuyển nhà về VPS — 6 Checkpoints
MIGRATION PLAN v2: CHUYỂN NHÀ VỀ VPS — 6 CHECKPOINTS
S109 | 11/03/2026 | Huyen phê duyệt | v2 — sau kiểm tra thực tế
search_knowledge("migration plan chuyển nhà VPS")
BỐI CẢNH
GCP đốt ₫45K/ngày do cross-region transfer (VPS EU ↔ GCP Singapore).
Chuyển tất cả về VPS, chỉ giữ Secret Manager ($2/tháng).
PHÁT HIỆN TỪ KIỂM TRA THỰC TẾ (11/03/2026):
- PostgreSQL 16 chạy rồi (container
workflow-postgres, healthy 11 ngày) - PG nằm compose RIÊNG (
nuxt-repo/web/.directus/docker-compose.yaml) → cần merge - Firestore: 4 core files, server.py nặng nhất (~20 refs) → MEDIUM-HIGH
- GCS Bucket: 2 files, LOW complexity (chỉ ingestion) → nhanh hơn dự kiến
- ⚠️ Agent-data + Nuxt image pull từ Artifact Registry → CP-1 PHẢI XONG TRƯỚC disable billing
- Disk: 59GB available / 96GB total → đủ
- 14 secrets, phần lớn cần giữ
THỨ TỰ BẮT BUỘC
CP-0 Consolidate Docker + Backup ← chuẩn bị
CP-1 Artifact Registry → GH Direct ← BẮT BUỘC TRƯỚC disable billing
CP-B DISABLE BILLING GCP ← chỉ sau CP-1 xong
CP-2 GCS Buckets → VPS Local ← 0.5-1 ngày (giảm từ 1.5)
CP-3 Firestore → PostgreSQL ← 2-3 ngày (core)
CP-4 Verify + Cleanup ← 1 ngày
CP-5 Domain migration (bonus) ← song song
CP-0: CONSOLIDATE DOCKER + BACKUP (Ngày 0, ~0.5 ngày)
⚠️ KHÔNG disable billing ở bước này — agent-data + nuxt vẫn cần pull image từ AR!
Checklist:
- Upload Luật Hạ tầng VPS
- Cập nhật Hiến pháp v3.2
- Merge
workflow-postgresvào main/opt/incomex/docker/docker-compose.yml:- Thêm postgres service, volume mapping, network
- Đổi container_name →
postgres(khớp migration commands) - Đảm bảo cùng Docker network với agent-data
- Tạo database + user:
docker exec postgres psql -U postgres -c "CREATE DATABASE incomex_metadata;"docker exec postgres psql -U postgres -c "CREATE USER incomex WITH PASSWORD '***';"docker exec postgres psql -U postgres -c "GRANT ALL ON DATABASE incomex_metadata TO incomex;" - Backup Firestore:
gcloud firestore export gs://[BUCKET]/firestore-backup-pre-migration/ - Backup Buckets:
gsutil -m rsync -r gs://huyen1974_agent_data_knowledge_test /opt/incomex/backups/gcs-pre-migration/
Verify:
-
docker exec postgres psql -U incomex -d incomex_metadata -c "SELECT 1;"→ OK -
docker compose ps→ postgres healthy trong main compose - Backup files tồn tại
CP-1: ARTIFACT REGISTRY → GH DIRECT DEPLOY (Ngày 1, ~0.5 ngày)
⚠️ PHẢI XONG trước disable billing — nếu không, agent-data + nuxt không deploy được!
Thực tế phát hiện:
- agent-data-test ĐÃ CÓ
deploy-vps.ymlnhưng vẫn pull image từ AR - web-test có proven pattern: GH Actions → build → SSH push → docker compose up
- Cần refactor: build image trên GH Actions/VPS, KHÔNG pull từ AR
Checklist:
- Refactor
deploy-vps.ymlcho agent-data-test: bỏ AR pull, build local hoặc GH Actions build + scp - Disable/xóa
artifact-registry-cd.ymlworkflow - Đảm bảo Nuxt deploy cũng không phụ thuộc AR (kiểm tra nuxt workflow)
- Test: push commit → build → deploy → health check pass
Verify:
-
curl https://vps.incomexsaigoncorp.vn/api/health→ 200 sau deploy mới (KHÔNG dùng AR) - Pipeline GREEN trên GitHub Actions
- Không có
asia-southeast1-docker.pkg.devtrong workflow files
CP-B: DISABLE BILLING GCP (Ngay sau CP-1 pass)
Chỉ thực hiện SAU KHI CP-1 verify thành công.
Checklist:
- GCP Console → Billing → Account Management → Actions (⋮) cạnh Github-chatgpt → Disable billing
- HOẶC: Huyen xác nhận cho tôi thao tác qua Computer Use
Verify:
- Deploy agent-data vẫn hoạt động (không phụ thuộc AR)
- Deploy nuxt vẫn hoạt động
-
curl https://vps.incomexsaigoncorp.vn/api/health→ 200 - Billing reports: chi phí giảm xuống ~₫0 (trừ Secret Manager)
CP-2: GCS BUCKETS → VPS LOCAL STORAGE (Ngày 1-2, ~0.5-1 ngày — giảm từ 1.5)
Thực tế: Chỉ 2 files dùng GCS (server.py, main.py), LOW complexity — chỉ ingestion.
⚠️ CP-0 phát hiện: Bucket huyen1974_agent_data_knowledge_test trả 404 — có thể đã xóa. Chỉ còn huyen1974-system-backups-shared (13 postgres backup files, 60KB). CP-2 có thể đơn giản hơn dự kiến.
Checklist:
- Tạo
/opt/incomex/data/storage/{uploads,knowledge,exports,snapshots,logs} - Sync:
gsutil -m rsync -r gs://huyen1974_agent_data_knowledge_test /opt/incomex/data/storage/knowledge/ - Refactor 2 files: thay
google.cloud.storage→ local filesystem - Cập nhật .env:
STORAGE_PATH=/opt/incomex/data/storage - Cấu hình Nginx serve static files (nếu cần public access)
Verify:
- Ingestion hoạt động từ local files
- Không còn import
google.cloud.storagetrong code -
df -h< 85%
CP-3: FIRESTORE → POSTGRESQL (Ngày 2-4, ~2-3 ngày) ⭐ QUAN TRỌNG NHẤT
Thực tế: 4 core files, server.py nặng nhất (~20 Firestore refs). Collections: kb_documents (chính), chat sessions/memory.
Chiến lược: Giữ nguyên interface _firestore(), thay backend → PostgreSQL
Checklist:
- Export Firestore collections → JSON
- Thiết kế PostgreSQL tables cho kb_documents + chat memory
- Import data JSON → PostgreSQL
- Refactor 4 files:
server.py: thay_firestore()→ PostgreSQL queries (~20 calls)main.py: thayfirestore.Client()→ PostgreSQL connectionresilient_client.py: thayprobe_firestore()→probe_postgres()memory.py: thay Firestore chat memory → PostgreSQL
- Cập nhật requirements.txt: bỏ firebase-admin, thêm asyncpg/psycopg2
- Cập nhật .env:
POSTGRES_URL=postgresql://incomex:***@postgres:5432/incomex_metadata - Test từng endpoint: CRUD, search, list, health
Verify:
- Tất cả API endpoints đúng (so sánh với Firestore data)
- Latency < 10ms (local PG) vs >100ms (Firestore trước đó)
-
grep -r "firestore\|firebase" /app/ --include="*.py"→ 0 results (trừ comments) - Health check: postgres probe thay firestore probe
CP-4: VERIFY + CLEANUP (Ngày 5-6, ~1 ngày)
Trước CP-4: CP-3B — DIRECTUS MYSQL → POSTGRESQL (~1 ngày)
Mục tiêu: Directus chạy trên PostgreSQL thay MySQL. Retire MySQL. 1 database engine duy nhất.
Cách làm tổng quát:
- Export MySQL data (mysqldump hoặc Directus schema migration)
- Tạo Directus database trên PostgreSQL
- Import data → PG
- Đổi Directus config: DB_CLIENT=pg, DB_HOST=postgres, DB_DATABASE=directus
- Verify Directus hoạt động bình thường
- Retire MySQL container
Verify: Directus healthy, tất cả collections/items/flows hoạt động, MySQL container removed.
Checklist CP-4:
- Monitor 24h: logs, errors, performance
- Cập nhật: infrastructure context pack, VPS spec, CLAUDE.md, AGENTS.md, skills
- Report:
knowledge/current-state/reports/vps-migration-complete-report.md - GCP cleanup: xóa buckets rỗng, disable APIs không dùng
- Xóa secrets không cần: GCS_BUCKET_BACKUP, Qdrant legacy
Verify:
- Health 200, billing ≤₫52K/tháng, docs phản ánh thực tế
CP-5: DOMAIN MIGRATION (bonus, song song)
- DNS: ai.incomexsaigoncorp.vn → A record 38.242.240.89
- Certbot SSL + Nginx server block cho ai. domain
- Disable Firebase Hosting
- Verify:
curl https://ai.incomexsaigoncorp.vn→ 200
TIMELINE v2
Ngày 0: CP-0 Consolidate Docker + Backup ✅ DONE
Ngày 1: CP-1 Artifact → Direct Deploy ✅ DONE
CP-2+CP-3 Buckets+Firestore → PG [Claude Code] ← ĐANG LÀM
Ngày 2-4: CP-2+CP-3 tiếp tục [Claude Code]
Ngày 4-5: CP-3B Directus MySQL → PostgreSQL [Claude Code]
CP-B Disable billing GCP [Huyen — sau xác nhận ổn định]
Ngày 5-6: CP-4 Verify + Cleanup [Claude + Computer Use]
Song song: CP-5 Domain migration [Claude Code]
Tổng: 5-6 ngày (giảm từ 5-6 nhờ CP-2 nhanh hơn, +1 ngày CP-3B)
CHI PHÍ TRƯỚC → SAU
| Trước | Sau | |
|---|---|---|
| GCP | ~$58/tháng | ~$2/tháng |
| VPS | $8/tháng | $8/tháng |
| VPS RAM/Disk | MySQL + PG chạy song song | Chỉ PG — tiết kiệm ~1-2GB RAM |
| Tổng | $66/tháng | $10/tháng |
| Tiết kiệm | 85% (~$672/năm) |
Migration Plan v2.0 | S109 | 6 Checkpoints (CP-0,1,B,2,3,4,5) | Target: 4-5 ngày