Instruction file imported from thanhquyen129/CMS (
.cursor/rules/deployment.mdc). Copyright stays with the author.
Deployment Standards / Chuẩn Deployment
Environments / Môi trường
- Separate local / staging / production configs. Never share prod secrets with lower envs.
- Tách config local / staging / production. Không chia sẻ secret prod cho môi trường thấp hơn.
- Infrastructure as code when possible (compose/K8s/Terraform). Document one-command deploy path.
- Infrastructure as code khi có thể. Có đường deploy một lệnh được ghi rõ.
Domain & TLS / Domain & SSL
- Custom domain via DNS (A/AAAA/CNAME) → reverse proxy or cloud load balancer.
- Domain qua DNS (A/AAAA/CNAME) → reverse proxy hoặc load balancer cloud.
- HTTPS only in staging/prod. Terminate TLS at edge (Caddy/Nginx/Traefik/cloud LB). Redirect HTTP→HTTPS.
- Staging/prod chỉ HTTPS. Terminate TLS ở edge. Redirect HTTP→HTTPS.
- Use managed certificates (Let's Encrypt / cloud certs). Auto-renew; alert on expiry.
- Dùng cert quản lý (Let's Encrypt / cloud). Tự renew; alert khi gần hết hạn.
- HSTS in production once HTTPS is stable. Prefer TLS 1.2+.
- HSTS trên production khi HTTPS ổn định. Ưu tiên TLS 1.2+.
Env vars & secrets / Biến môi trường & secret
- Config via env / secret manager — never commit
.envwith real secrets, connection strings, or private keys. - Config qua env / secret manager — không commit
.envcó secret thật, connection string, private key. - Provide
.env.examplewith dummy values and required keys documented. - Có
.env.examplegiá trị giả + liệt kê key bắt buộc. - ASP.NET:
appsettings.jsonfor non-secrets; secrets in env / User Secrets (dev) / vault (prod). - ASP.NET:
appsettings.jsoncho non-secret; secret ở env / User Secrets (dev) / vault (prod). - Different connection strings per env. Fail fast on missing required config at startup.
- Connection string khác nhau từng env. Fail fast nếu thiếu config bắt buộc lúc startup.
Process & networking / Process & mạng
- Bind app to internal port; expose 80/443 only via proxy. Health:
/healthlive +/ready(DB/deps). - App listen port nội bộ; chỉ mở 80/443 qua proxy. Health:
/healthlive +/ready(DB/deps). - Host Compose: Postgres/Redis/API/web use
expose(or no host ports). Neverports: "5432:5432"/"6379:6379"/"11434:11434"on production. - Compose host: Postgres/Redis/API/web dùng
expose(hoặc không map host). Cấmports: "5432:5432"/"6379:6379"/"11434:11434"trên production. - Run as non-root in containers. Required on prod:
mem_limit(and prefercpus/pids_limit) per service so one container cannot OOM the host. - Container chạy non-root. Bắt buộc trên prod:
mem_limit(nên cócpus/pids_limit) mỗi service — một container không được OOM cả máy. - Reverse proxy must rate-limit by IP and drop common scan/auth-bypass headers before traffic hits Next.js/API.
- Reverse proxy phải rate-limit theo IP và drop header scan/bypass auth phổ biến trước khi tới Next.js/API.
- Keep
/metricsand debug routes off the public internet (auth or internal-only). - Giữ
/metricsvà route debug khỏi internet công khai (auth hoặc chỉ nội bộ). - Migrations: run as controlled release step, not raced by every replica on boot (unless locked migrator).
- Migration: bước release có kiểm soát, không để mọi replica đua migrate lúc boot (trừ migrator có lock).
- Prod change window + rollback owner named before risky deploys. Prefer forward-fix migrations.
- Thay đổi prod: có cửa sổ + người rollback trước khi deploy rủi ro. Ưu tiên migration forward-fix.
- Pre-deploy 30s check: published ports, container limits, secrets not in image/logs, known critical CVEs on edge frameworks.
- Kiểm tra 30 giây trước deploy: port đã publish, limit container, secret không trong image/log, CVE critical đã biết trên framework mép.