- Dùng 3 VPS riêng cho dev, staging, prod để tránh đè data và crash chéo.
- DNS đặt theo subdomain: dev.app.com, staging.app.com, app.com - mỗi VPS 1 IP riêng.
- Pipeline promote: dev (push tự deploy) -> staging (manual approve) -> prod (tag release).
- Mỗi env có biến .env riêng, DB riêng, S3 bucket riêng - không bao giờ share secret giữa env.
- Cloud VPS TND 199k-599k/tháng đủ chạy 3 env cho dev solo, snapshot trước mỗi promote.
Nếu bạn đang code 1 app SaaS trên VPS duy nhất, push thẳng lên production rồi cầu nguyện - thì bài này dành cho bạn. Tách 3 environment ra 3 VPS riêng không phải là chuyện chỉ enterprise mới làm. Với 3 con Cloud VPS tầm 199k-599k/tháng, dev solo cũng đủ ngân sách dựng pipeline pro level: dev để code thử, staging để QA, prod để khách dùng.
Lý do tách hẳn ra 3 VPS thay vì 3 docker-compose trên 1 máy là cô lập tài nguyên: dev có thể nuốt RAM khi chạy nodemon, staging có thể restart liên tục khi QA test, prod cần ổn định tuyệt đối. Chung VPS thì 1 lệnh sai có thể đè data hoặc kill process của env khác.
Bài này hướng dẫn full pipeline: cấu hình 3 VPS, đặt DNS subdomain, viết script deploy promote tự động, tách database, tách secret, và rollback khi prod fail. Dùng được cho Next.js, NestJS, Django hay bất kỳ stack nào - vì logic env tách giống nhau.
1. Vì sao phải tách 3 VPS thay vì 1 VPS chạy 3 container?
Nhiều dev solo hay nghĩ: dựng 3 docker-compose trên 1 con VPS 8GB là xong. Đúng, rẻ hơn thật. Nhưng có 4 vấn đề lớn xảy ra khi scale:
- RAM contention: dev chạy webpack-dev-server thường ăn 1-2GB, staging chạy Playwright test ăn 1GB nữa, prod chỉ còn 4GB cho user thật.
- Risk lan chéo: 1 lệnh docker volume rm sai có thể xóa cả 3 DB nếu naming trùng.
- Network port collision: 3 env đều muốn port 3000, 5432, 6379 - phải mapping lằng nhằng, dễ nhầm.
- Maintenance window: restart Docker daemon kill cả 3 env cùng lúc, prod down theo dev.
Còn tách 3 VPS riêng thì bạn ngủ yên hơn: dev crash không ảnh hưởng prod, snapshot từng env độc lập, scale prod lên 4GB mà dev vẫn 1GB tiết kiệm tiền.
2. Sizing 3 VPS phù hợp ngân sách dev solo
Đây là gợi ý sizing dựa trên stack Next.js + Postgres + Redis - stack phổ biến của vibe coder VN. Bạn có thể giảm hoặc tăng theo nhu cầu thực tế:
| Environment | RAM | CPU | Disk | Mục đích | Giá tham khảo |
|---|---|---|---|---|---|
| Dev | 2GB | 1 vCPU | 40GB SSD | Hot reload, test feature mới | 199k/tháng |
| Staging | 2GB | 1 vCPU | 40GB SSD | QA, run E2E test, demo khách | 199k/tháng |
| Prod | 4GB | 2 vCPU | 80GB SSD | User thật, traffic ổn định | 399k/tháng |
Tổng cộng khoảng 797k/tháng cho 3 VPS - bằng tiền 1 ly cafe Highlands mỗi ngày. So với việc 1 lần data loss làm mất tuần code, chi phí này quá rẻ.
3. Đặt DNS subdomain rõ ràng cho 3 env
Quy tắc đặt tên: prod ngắn nhất, staging và dev có prefix. Ví dụ với app.com:
- Prod: app.com hoặc www.app.com - point tới IP VPS prod.
- Staging: staging.app.com - point tới IP VPS staging, có basic auth hoặc IP whitelist.
- Dev: dev.app.com - point tới IP VPS dev, chỉ team nội bộ truy cập.
Set DNS A record trên Cloudflare (hoặc DNS provider khác) với TTL 300s để dễ đổi IP khi cần migrate VPS:
# Cloudflare DNS records
app.com A 1.2.3.4 (proxied)
www.app.com A 1.2.3.4 (proxied)
staging.app.com A 5.6.7.8 (DNS only - không proxy để basic auth chạy)
dev.app.com A 9.10.11.12 (DNS only)Cấp Let Encrypt SSL cho từng subdomain riêng bằng certbot hoặc Caddy auto-HTTPS. Đừng dùng wildcard cert cho tiện - vì 1 lần expire là cả 3 env down.
4. Tách database riêng cho từng env
Đây là nguyên tắc bất di bất dịch: không bao giờ share database giữa 3 env. Dev có thể chạy migration phá schema, staging có data test giả, prod có data thật của khách. Trộn lẫn 1 lần là mất hết.
Cài Postgres trên cả 3 VPS, mỗi env có DB tên đầy đủ rõ ràng:
# SSH vào VPS dev
sudo -u postgres psql
CREATE DATABASE app_dev;
CREATE USER app_dev_user WITH PASSWORD 'random_strong_pwd';
GRANT ALL PRIVILEGES ON DATABASE app_dev TO app_dev_user;
# SSH vào VPS staging - DB tên app_staging
# SSH vào VPS prod - DB tên app_prod
# Pg_hba.conf: chỉ cho local connection
host app_prod app_prod_user 127.0.0.1/32 scram-sha-256Backup tự động hàng ngày bằng cron + pg_dump, upload lên S3-compatible (Cloudflare R2 hoặc Backblaze B2 rẻ). Prod nên backup mỗi 6 giờ, staging và dev mỗi ngày 1 lần.
5. Quản lý secret và biến .env theo env
Mỗi VPS có file .env riêng tại /var/app/.env, owner root:root, chmod 600. Không bao giờ commit .env lên git, không bao giờ copy .env prod sang dev.
# /var/app/.env trên VPS dev
NODE_ENV=development
DATABASE_URL=postgres://app_dev_user:[email protected]:5432/app_dev
REDIS_URL=redis://127.0.0.1:6379/0
STRIPE_KEY=sk_test_xxx
SENTRY_DSN=https://[email protected]/123
# /var/app/.env trên VPS staging
NODE_ENV=staging
DATABASE_URL=postgres://app_staging_user:[email protected]:5432/app_staging
STRIPE_KEY=sk_test_yyy # vẫn test key
SENTRY_DSN=https://[email protected]/124
# /var/app/.env trên VPS prod
NODE_ENV=production
DATABASE_URL=postgres://app_prod_user:[email protected]:5432/app_prod
STRIPE_KEY=sk_live_zzz # live key thật
SENTRY_DSN=https://[email protected]/125Nếu team có 2-3 dev, dùng tool quản lý secret như Vault hoặc Doppler để sync .env giữa các máy local mà không paste qua Slack.
6. Pipeline deploy: push code chảy từ dev xuống prod
Flow chuẩn cho team nhỏ:
- Branch
develop: push tự deploy lên dev.app.com qua webhook GitHub Actions. - Branch
staging: merge từ develop, deploy lên staging.app.com, QA test 1-2 ngày. - Branch
main+ tag releasev1.2.3: deploy lên prod.app.com, manual approve.
Script deploy đơn giản chạy trên VPS, kéo code mới về và restart service systemd:
#!/bin/bash
# /var/app/deploy.sh
set -e
cd /var/app
git fetch --all
git reset --hard origin/$BRANCH
npm ci --production
npm run build
# Migrate DB (chỉ chạy ở staging+prod, dev tự migrate local)
if [ "$NODE_ENV" != "development" ]; then
npm run db:migrate
fi
sudo systemctl restart app.service
sudo systemctl status app.serviceTrên VPS prod, thêm bước snapshot Cloud VPS trước khi deploy - 1-click qua TND panel hoặc API. Nếu deploy lỗi thì rollback snapshot trong 2 phút.
7. GitHub Actions webhook trigger deploy 3 env
Setup 3 workflow riêng trong .github/workflows/, mỗi workflow trigger theo branch khác nhau:
# .github/workflows/deploy-dev.yml
name: Deploy Dev
on:
push:
branches: [develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: SSH deploy
uses: appleboy/ssh-action@v1
with:
host: dev.app.com
username: deploy
key: ${{ secrets.SSH_KEY_DEV }}
script: |
cd /var/app
BRANCH=develop ./deploy.shWorkflow deploy-staging.yml và deploy-prod.yml tương tự, đổi branch và host. Prod thêm environment: production + required reviewers để 1 dev khác phải approve mới deploy.
8. Feature flag và database migration an toàn
Khi promote code từ dev xuống prod, lo nhất là migration phá DB prod. 3 nguyên tắc bắt buộc:
- Backward compatible migration: thêm column mới với default value, đừng rename trực tiếp. Code mới đọc col mới, code cũ vẫn chạy được.
- Test migration ở staging trước: import production data (đã anonymize PII) vào staging, chạy migrate, đo thời gian.
- Feature flag: dùng tool như Unleash hoặc LaunchDarkly self-host. Deploy code có feature mới ở off, bật on cho 5% user, theo dõi metric, rồi full rollout.
9. Monitoring và alert riêng cho từng env
Cài Uptime Kuma (self-host) hoặc dùng UptimeRobot free monitor 3 URL: dev, staging, prod. Set alert level khác nhau:
- Prod down: gọi điện thoại + SMS + email + push Telegram.
- Staging down: chỉ email + Telegram channel.
- Dev down: silent log, dev tự fix khi quay lại làm.
Sentry cũng setup 3 project riêng cho 3 env, tag environment để filter log theo dev/staging/prod khi debug. Tránh trộn lẫn lỗi dev (do code lỗi) với lỗi prod (do user thật gặp).
10. Rollback nhanh khi prod fail
Có 3 mức rollback từ nhẹ tới nặng:
- Code rollback:
git reset --hard HEAD~1rồi chạy lại deploy.sh - mất 30 giây, không mất data. - DB rollback: chạy migration down nếu có, hoặc restore pg_dump snapshot gần nhất - mất 5-10 phút.
- Full VPS rollback: restore snapshot Cloud VPS trước deploy - mất 2-3 phút, mất toàn bộ data sau snapshot.
Luôn snapshot VPS prod TRƯỚC khi deploy, dù dev tin tưởng staging đã test xong. Trên Cloud VPS TND có nút Snapshot 1-click trong panel - 5 giây xong.
11. Chi phí thực tế cho startup 6 tháng đầu
| Tháng | Setup | Chi phí/tháng | Ghi chú |
|---|---|---|---|
| 1-2 | 1 VPS 4GB chung 3 env | 399k | MVP, ít traffic, chấp nhận risk |
| 3-4 | Tách prod ra 1 VPS, dev+staging chung | 598k | Khi có 10-50 user thật |
| 5-6 | Tách hẳn 3 VPS | 797k | Khi pipeline ổn định, deploy hằng tuần |
| 7+ | Scale prod lên 8GB, thêm staging riêng | 1190k | Khi có traffic ổn 500+ user/ngày |
Chi phí tăng dần theo độ trưởng thành của startup, không cần đốt tiền cloud từ ngày đầu. Cloud VPS TND có resize CPU/RAM 1-click, snapshot trước khi resize an toàn.
12. Checklist trước khi go-live 3 env
- 3 VPS đã có SSL, firewall mở 80/443/22 thôi.
- 3 DB riêng biệt, backup tự động lên S3.
- 3 file .env riêng, không có secret chéo env.
- 3 systemd service chạy app, auto-restart khi crash.
- 3 subdomain DNS đúng, SSL active.
- 3 GitHub Actions workflow trigger theo branch.
- 3 Sentry project + 3 Uptime monitor.
- Snapshot policy: prod 6h/lần, staging+dev 24h/lần.
- Runbook rollback in giấy, dán cạnh máy.
3 VPS riêng cho dev, staging, prod chỉ từ 597k/tháng
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Tách 3 environment ngay từ ngày đầu, ngủ yên không lo đè data prod.
Xem 8 cấu hình Cloud VPS →FAQ
Có nên dùng Docker Compose chạy 3 env trên 1 VPS để tiết kiệm?
Tiết kiệm thật nhưng risk cao. Khi có lệnh sai hoặc Docker daemon crash thì cả 3 env down. Tách 3 VPS chỉ tốn thêm 400k/tháng nhưng cô lập hoàn toàn, đáng tiền.
Database staging có nên dùng data thật từ prod?
Nên dùng nhưng phải anonymize PII (email, phone, address) trước khi import. Có script pg_dump | sed replace email thật bằng email random. Đừng để dev nhìn thấy data khách thật.
Cần CI/CD pipeline phức tạp như Jenkins không?
Không. GitHub Actions free 2000 phút/tháng đủ cho team nhỏ. Setup workflow .yml chỉ 30 dòng là deploy được. Jenkins phức tạp dành cho enterprise 50+ dev.
Làm sao test migration mà không phá staging DB?
Trước khi chạy migration thật, dump staging DB ra file. Chạy migration. Nếu fail thì restore lại. Hoặc dùng transaction wrap migration để rollback tự động khi error.
VPS staging có cần SSL không?
Có. Vì cookie session, OAuth callback đều yêu cầu HTTPS. Caddy auto cấp Let Encrypt cho subdomain staging.app.com chỉ với 1 dòng config, miễn phí.
Có nên dùng same SSH key cho cả 3 VPS?
Không nên. Tạo 3 key riêng: id_ed25519_dev, id_ed25519_staging, id_ed25519_prod. Nếu 1 key bị leak thì chỉ 1 env compromise, không lan sang cái khác.
- OpenClaw + Zalo: tự động hóa Zalo cá nhân và Zalo OA bằng AI agent
- Tại sao chọn IIS 7.5 ?
- Proxy cho SEO SERP tracking 2026: multi-country
- OpenClaw vs AnythingLLM vs Open WebUI: chọn personal AI tự host nào cho VN?
- PostgreSQL backup tự động trên VPS qua pg_dump + cron + S3
- Setup PM2 cho Node.js production trên VPS: auto-restart, log rotation



