Deployment Guide

คู่มือ deploy reverse proxy stack ไปยังเครื่องจริงสำหรับ domain https://<PUBLIC_APP_HOST> และ route /projects/demo1/.

Production Target

Item Value
Domain https://<PUBLIC_APP_HOST>
Demo path /projects/demo1/
Server path <DEPLOY_PATH> หรือ /opt/<stack-name>/services
Proxy container <NGINX_CONTAINER>
App container <APP_SERVICE>

Deployment Steps

Run pre-deploy quality gates

ก่อน copy ขึ้น EC2 ต้องผ่าน dependency audit, build, compose config, SonarQube Quality Gate และ image scan. ถ้า gate ไม่ผ่านให้แก้ที่ local/CI ก่อน deploy.

cd <REPO_ROOT>
./scripts/quality-gate.sh

cd services
docker compose -f docker-compose.local.yml --profile quality up -d sonarqube sonar-postgres

# ตัวอย่าง scanner (ใช้ secret จาก CI/ENV; ห้ามใส่ค่า token ในไฟล์)
docker run --rm -v "$PWD/..:/usr/src" sonarsource/sonar-scanner-cli \
  -Dsonar.host.url=http://host.docker.internal:9000 \
  -Dsonar.token="${SCAN_TOKEN_ENV}"
ห้ามกรอก token จริงลงเอกสาร, commit diff, หรือ command history ในเครื่องคนทำงาน. ใช้ CI secret/env var เท่านั้น.

Copy source to server

ให้ source อยู่ที่ <DEPLOY_PATH>. โครงสร้างต้องมี docker-compose.yml, nginx/, portal/, และ projects/demo1/.

Check certificate files

production config mount /etc/letsencrypt. ต้องมี certificate สำหรับ domain ก่อนเปิด HTTPS server.

sudo ls -la /etc/letsencrypt/live/<PUBLIC_APP_HOST>/

Build and start

cd <DEPLOY_PATH>
docker compose up --build -d

Validate containers

docker compose ps
docker logs --tail 80 <NGINX_CONTAINER>
docker logs --tail 80 <APP_SERVICE>

Validate nginx

docker exec <NGINX_CONTAINER> nginx -t
docker exec <NGINX_CONTAINER> nginx -s reload

Validate public route

curl -sL -o /dev/null -w '%{http_code} %{url_effective}\n' https://<PUBLIC_APP_HOST>/projects/demo1/
curl -sL -o /dev/null -w '%{http_code} %{url_effective}\n' https://<PUBLIC_APP_HOST>/projects/demo1/foreman
curl -sL -o /dev/null -w '%{http_code} %{url_effective}\n' https://<PUBLIC_APP_HOST>/projects/demo1-ms/
curl -sL -o /dev/null -w '%{http_code} %{url_effective}\n' https://<PUBLIC_APP_HOST>/pipeline/
curl -sL https://<PUBLIC_APP_HOST>/projects/demo1/ | grep -o '/projects/demo1/_next/[^\" ]*' | head

Expected Result

หน้า https://<PUBLIC_APP_HOST>/projects/demo1/ ควรเปิดได้ และ asset path ต้องเป็น /projects/demo1/_next/....

Rollback

ถ้า deploy แล้ว route เสีย ให้ดู container เดิมก่อนลบอะไรเสมอ.

cd <DEPLOY_PATH>
docker compose ps
docker compose logs --tail 120 <NGINX_CONTAINER>
docker compose logs --tail 120 <APP_SERVICE>

ถ้าต้องหยุด stack:

docker compose down
อย่าใช้คำสั่งลบ volume หรือ prune ทั้งระบบจนกว่าจะยืนยันว่าไม่มีข้อมูลหรือ container อื่นใช้งานอยู่.

Common Fixes

Port 80 or 443 already allocated

sudo lsof -i :80
sudo lsof -i :443
docker ps --format 'table {{.Names}}\t{{.Ports}}'

nginx cannot find upstream

ตรวจว่า service อยู่ network เดียวกัน และชื่อ service ตรงกับ nginx upstream.

docker network inspect <DOCKER_NETWORK>
docker exec <NGINX_CONTAINER> getent hosts <APP_SERVICE>

App opens but assets fail

ตรวจ NEXT_PUBLIC_BASE_PATH และ rebuild image.

docker compose build <APP_SERVICE>
docker compose up -d <APP_SERVICE> <NGINX_CONTAINER>