Skip to content

13.1 Hosting topology & environment matrix

ภาพรวม — ระบบผสมระหว่าง cloud และ on-prem

ระบบ VTRC ไม่ได้รันอยู่บนแพลตฟอร์มเดียว แต่ผสมระหว่าง GCP สำหรับ container runtime และ on-prem สำหรับ database และ identity service (LDAP/AD)

                     ┌─────────────────────────────────────────────────────┐
                     │  GCP project: vtrc-nonprod (container registry)     │
                     │  gcr.io/vtrc-nonprod/...                            │
                     └─────────────────────────────────────────────────────┘
                                          │ docker pull

┌─────────────────────────────────────────────────────────────────────────────────┐
│  Production VM                                                                   │
│                                                                                  │
│  nginx (443/80) ──┬── vtrc-api replica ×4 (APP_NO=1,2,3,5) port 8081            │
│                   ├── vtrc-web nginx serve build/                                │
│                   └── cu-central-api replica ×3 (APP_NO=1,2,3)                  │
│                                                                                  │
│  Redis 6379 (container)                                                          │
│                                                                                  │
│  ※ centralize-api (NestJS :3000) มีใน workspace แต่ยังไม่ยืนยันว่าอยู่ใน         │
│    path ของ nginx production (ดู E-08 ด้านล่าง)                                 │
└─────────────────────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────────────┐
│  On-prem                                                                         │
│  ├── MariaDB — schema vtrc + vtrc-centralize                                    │
│  ├── MSSQL — HRMI (HR data)                                                     │
│  └── LDAP/AD — sso.redcross.or.th (10.188.128.213)                              │
└─────────────────────────────────────────────────────────────────────────────────┘

โดเมนที่ใช้งาน

ระบบเลือก endpoint ของ GraphQL ตามโดเมนที่ผู้ใช้เข้าถึง — กลไกนี้ฝังอยู่ใน vtrc-web/src/config/apollo.js (รายละเอียดเต็มใน Volume 6)

OriginGraphQL endpointสภาพแวดล้อม
https://vtrc.redcross.or.th/https://vtrcapi.redcross.or.th/api/graphqlproduction
https://vtrcbackoffice.redcross.or.th/https://vtrcapi.redcross.or.th/api/graphqlproduction
https://uat-vtrc.redcross.or.th/https://uat-vtrcapi.redcross.or.th/api-uat/graphqlUAT
https://uat-vtrcbackoffice.redcross.or.th/https://uat-vtrcapi.redcross.or.th/api-uat/graphqlUAT
http://localhost:3000/ชี้ไป UATพัฒนาเครื่อง local

โดเมนที่ nginx รู้จัก (จาก server_name ใน config):

โดเมนไฟล์ nginxจุดประสงค์
vtrcapi.redcross.or.thvtrc-api/nginx/default.conf:43,57API endpoint (หลัก)
vtrc.redcross.or.thvtrc-api/nginx/default.conf:51,211เว็บ end-user
centralizeapi.redcross.or.thcu-central-api/nginx/default.conf:66,110centralize / cu-central gateway
sso.redcross.or.th, ssoapi.redcross.or.thcu-central-api/docker-compose.yml:55LDAP/AD on-prem

กลยุทธ์ GCP + on-prem แบบผสม

จาก docker-compose และ Dockerfile ของทั้งระบบ พบว่า:

  1. Container image เก็บใน GCRcu-central-api/docker-compose.yml:39 อ้างถึง gcr.io/vtrc-nonprod/cu-centralize-api:latest และ Bitbucket Pipelines push image ไปยัง $GCP_REGISTRY_HOSTNAME/$GCP_PROJECT_ID/... (vtrc-api/bitbucket-pipelines.yml:56)

  2. Container runtime รันบน VM (ไม่ใช่ GKE) — ไม่มีไฟล์ Kubernetes manifest, ไม่มี Deployment.yaml, ไม่มี Service.yaml ทุก service ใช้ docker-compose.ymlnetwork_mode: host ใส่เฉพาะ service nginx (vtrc-web-proxy / rc-web-proxy) ไม่ใช่ทุก container (vtrc-api/docker-compose.yml:34, cu-central-api/docker-compose.yml:35)

  3. Database และ LDAP อยู่ on-premcu-central-api/docker-compose.yml:54-55 กำหนด extra_hosts สำหรับ sso.redcross.or.th ชี้ไป IP 10.188.128.213 (private IP on-prem) เพื่อให้ container ใน GCP เรียก LDAP ได้ผ่านทาง network ที่เชื่อมระหว่างกัน

  4. ไม่มี workload identity, ไม่มี KMSvtrc-api/vtrc-gcp-sa-key.json เป็น GCP service account key ที่ commit ลง repository (รายละเอียดใน Volume 9 บทที่ 5)

Environment matrix

สภาพแวดล้อมvtrc-apicu-central-apicentralize-apivtrc-webvtrc-rc-backoffice
Productiondocker-compose.yml, 4 replicasdocker-compose.yml, 3 replicasdocker-compose.yml, 1 replicanginx serve buildnginx serve build
UATdocker-compose.dev.ymldocker-compose-dev.ymldocker-compose.yml (target: dev)build เดียวกัน ใช้ URL เป็นตัวเลือกbuild เดียวกัน ใช้ URL เป็นตัวเลือก
พัฒนาเครื่อง localnpm run (nodemon)npm run (nodemon)yarn start:devnpm startnpm start

จุดสังเกต:

  • Frontend ทั้งสองตัว (vtrc-web, vtrc-rc-backoffice) ไม่มีการ build แยก production/UAT — ตัวเลือก environment ฝังอยู่ใน checkLinkURL() ที่อ่าน window.location.href ในขณะรัน (รายละเอียดเต็มใน Volume 6 และ Volume 7)
  • centralize-api ใช้ docker-compose เดียวกันทั้ง dev และ prod โดยต่างกันที่ target: develop หรือ target: production (centralize-api/docker-compose.yml:5-6,18-19)

โครงสร้าง timezone

ทุก service ตั้งค่า timezone เป็น Asia/Bangkok ผ่าน environment variable:

  • vtrc-api/docker-compose.yml:55,68,81,94TZ=Asia/Bangkok สำหรับทุก replica
  • cu-central-api/docker-compose.yml:46,65,82 — เช่นเดียวกัน
  • centralize-api/Dockerfile:5ENV TZ="Asia/Bangkok"
  • vtrc-api/api/.env.example:10TIME_ZONE = 'Asia/Bangkok'

ส่วน front-end ใช้ locale พ.ศ. (พุทธศักราช) — รายละเอียดอยู่ใน Volume 6 บทที่ 8

E-08 · NestJS centralize-api กับ production nginx

centralize-api (NestJS, port 3000) มีใน workspace และมี docker-compose.yml ของตัวเอง แต่ cu-central-api/nginx/default.conf upstream centralized-api ชี้เฉพาะ localhost:8000, 8002, 8003 (cu-central GraphQL replicas) — ไม่มี upstream ไป NestJS :3000

ดังนั้นเอกสารนี้ ไม่ยืนยัน ว่า NestJS อยู่ใน path ของ nginx production ของ centralizeapi.redcross.or.th — ต้องสอบถามทีมปฏิบัติการก่อนสมมติว่า traffic จากโดเมนนั้นไปถึง NestJS

สรุปประเด็นสำคัญ

  • ระบบไม่ได้อยู่บน Kubernetes — ใช้ docker-compose บน VM; nginx ใช้ network_mode: host เพื่อ upstream ไป localhost:PORT ของ Node replica — การเพิ่ม/ลด replica ต้องแก้ docker-compose.yml เอง
  • database และ LDAP อยู่นอก GCP — ทำให้มีจุดเชื่อม network ระหว่าง cloud กับ on-prem ที่ต้องดูแลเป็นพิเศษ
  • Frontend เลือก environment จาก URL — ทำให้ build หนึ่งรอบใช้ได้ทั้ง prod และ UAT แต่ก็หมายความว่าไม่สามารถบังคับ environment จากฝั่ง build ได้
  • NestJS centralize-api ยังไม่ยืนยันใน nginx production path (E-08)