KB-6FF9
S115 MySQL to PostgreSQL Migration Report
3 min read Revision 1
S115 MySQL to PostgreSQL Migration — Final Report
Date: 2026-03-13 Status: COMPLETE PRs: #496 (infra), #497 (deploy fix), #498 (docs)
Root Cause of Deploy #165 Failure
-
Nginx stale DNS (502): When docker compose restart nuxt ran, the nuxt container got a new IP. Nginx had cached the old IP in its upstream resolver. The health check curl https://vps.incomexsaigoncorp.vn/ hit nginx which tried the stale IP -> 502 -> rollback triggered.
-
PG_PASSWORD missing: The new docker-compose.yml uses ${PG_PASSWORD} for the postgres service, but the VPS .env only had DB_PASSWORD. Docker Compose warned about the blank variable.
Fixes Applied
VPS (direct)
- Added PG_PASSWORD to /opt/incomex/docker/.env
- Ran nginx -s reload to clear stale DNS
PR #496 — feat: migrate Directus from MySQL to PostgreSQL
- infra/docker/docker-compose.yml: MySQL service replaced with PostgreSQL 16
- infra/docker/.env.example: MySQL vars replaced with PG vars
- dot/configs/directus.env.template: DB_CLIENT=pg, port 5432
- docker-compose.local.yml: Added migration note
- scripts/0047c_*.sh (3 files): Added DEPRECATED headers
PR #497 — fix: reload nginx after service restart
- Added nginx -s reload after service restarts in both deploy modes
- Prevents future stale DNS 502 errors during deploys
PR #498 — docs: MySQL retirement notes
- Added S115 amendment notes to 5 architecture docs
Verification
| Check | Result |
|---|---|
| Deploy GREEN | Deploy to VPS succeeded (run 23041779873) |
| DB_CLIENT=pg on VPS | Confirmed |
| MySQL container STOPPED | incomex-mysql Exited (0) |
| Directus healthy | status ok |
| API reads data | meta_catalog CAT-000 catalog |
| v_registry_counts works | CAT-000=20 CAT-001=20 CAT-002=4 |
| Site loads | HTTP 200 |
| Docs updated | 5 files with S115 amendment notes |
Architecture After Migration
- Database: PostgreSQL 16 (container: postgres)
- Directus: 11.5 with DB_CLIENT=pg DB_HOST=postgres DB_PORT=5432
- MySQL: RETIRED container stopped
- PG features: auto-code triggers CHECK constraints refresh_registry_counts() v7.0.0
Conclusion
MySQL RETIRED. PostgreSQL 16 = DB duy nhat cho Directus tren VPS.