Files
homaroma/TENANT_PROVISIONING_POSTMORTEM_CHECKLIST.md
T
2026-10-01 05:49:58 +07:00

7.8 KiB

สรุปปัญหา ข้อผิดพลาด และ Checklist การสร้าง Tenant / Subdomain ใหม่

Historical operational record: This postmortem preserves the facts of a 2026 tenant-provisioning incident. Existing HomAroma identifiers are legacy infrastructure references, not DBK Platform branding. (Tenant Provisioning Post-Mortem & Standard Operating Procedure)

บันทึกข้อผิดพลาดจากการสร้าง Showcase Subdomains (wellness, fashion, beauty, moto) บน kittisak.com เมื่อวันที่ 24 กันยายน 2026 เพื่อใช้เป็น Checklist ป้องกันการทำผิดพลาดซ้ำในอนาคต


1. ปัญหาและข้อผิดพลาดที่เกิดขึ้น (What Went Wrong)

ข้อผิดพลาดหลักที่ 1: ลืมรันคำสั่ง Seed ฐานข้อมูล (ตกหล่นขั้นตอนที่ 8 ของ DEPLOYMENT_GUIDE.md)

  • สิ่งที่เกิดขึ้น: หลังจากสร้างฐานข้อมูล PostgreSQL ใหม่ทั้ง 4 ตัว (wellness_db, fashion_db, beauty_db, moto_db) ได้ทำการรัน bunx prisma db push เพื่อสร้าง Table โครงสร้างเสร็จสิ้น แต่ไม่ได้รันคำสั่ง bun run prisma/seed.cjs
  • ผลกระทบ: ตาราง User ในฐานข้อมูลใหม่ทั้งหมดมีข้อมูล 0 คน เมื่อผู้ใช้พยายามล็อกอินเข้าหลังบ้าน (admin.<subdomain>.kittisak.com) ระบบ Backend จึงหาชื่อผู้ใช้ไม่พบ และส่ง Error 401 Unauthorized ทันที นอกจากนี้ข้อมูลตั้งต้น เช่น เมนู, หมวดหมู่ และสินค้าตัวอย่างก็ไม่มีในระบบ
  • สาเหตุที่พลาด: สรุปจบงานเร็วเกินไปหลังจากเช็ค HTTP 200 ของหน้าเว็บและหน้า API พื้นฐาน โดยไม่ได้ทำการทดสอบ Smoke Test ในส่วนของการ Login ด้วยบัญชี Admin จริง

ข้อผิดพลาดหลักที่ 2: วิเคราะห์ปัญหาออกนอกลู่นอกทาง (Over-complicating Troubleshooting)

  • สิ่งที่เกิดขึ้น: เมื่อเกิดปัญหา Login ไม่ได้ แทนที่จะกลับมาเปิดอ่าน DEPLOYMENT_GUIDE.md ที่ระบุขั้นตอนการ Seed และ User Admin ไว้อย่างชัดเจน กลับไปไล่แกะ Hash Password ใน Database และตั้งข้อสงสัยเรื่อง onParse ในโค้ด Backend
  • สาเหตุที่พลาด: ไม่ได้ยึดตาม Runbook ขั้นตอนการ Deploy มาตรฐานเป็น First Priority ในการตรวจสอบความสมบูรณ์ของระบบที่เพิ่งสร้างใหม่

2. Checklist การสร้าง Subdomain / Tenant ใหม่ (ห้ามข้ามขั้นตอนเด็ดขาด)

ทุกครั้งที่มีการสร้าง Domain หรือ Subdomain ใหม่ ต้องปฏิบัติตามลำดับขั้นตอนดังนี้:

Step 1: DNS & Port Allocation

  • กำหนดพอร์ตที่ไม่ซ้ำกับโปรเจกต์เดิม:
    • Backend API Port (เช่น 3055, 3056, ...)
    • Website SSR Port (เช่น 3006, 3007, ...)
  • ผูก DNS Records หรือ Wildcard A Record ชี้มาที่ IP เซิร์ฟเวอร์ให้เรียบร้อย

Step 2: Database Provisioning

  • สร้างฐานข้อมูลใหม่ใน PostgreSQL:
    docker exec -i arokro_postgres psql -U postgres -c "CREATE DATABASE <tenant>_db;"
    
  • Push Schema ตารางเข้าฐานข้อมูลใหม่:
    cd /home/ti/projects/<tenant>-api/apps/backend
    bunx prisma db push
    

Step 3: Database Seeding (จุดที่เคยลืม - บังคับทำทันที!)

  • รันคำสั่ง Seed ข้อมูลเริ่มต้นและบัญชี Admin:
    cd /home/ti/projects/<tenant>-api/apps/backend
    bun run prisma/seed.cjs
    
  • ตรวจสอบว่ามี Admin User ในตารางจริง:
    docker exec -i arokro_postgres psql -U postgres -d <tenant>_db -c "SELECT id, username, role FROM \"User\";"
    
    (ต้องเห็น user admin / role ADMIN จำนวน 1 แถว)

Step 4: Firewall & Network

  • เปิดพอร์ต Backend และ SSR ใน UFW:
    sudo ufw allow <BACKEND_PORT>/tcp
    sudo ufw allow <SSR_PORT>/tcp
    
  • ตรวจสอบว่ากฎ ufw-user-input ไม่บล็อกพอร์ตภายในเครื่อง

Step 5: Nginx & SSL Certbot

  • สร้าง Nginx Config สำหรับ 4 ส่วน:
    • main (SSR Website & Reverse Proxy ไปที่ SSR Port)
    • api (Reverse Proxy ไปที่ Backend Port)
    • spa (Static Web Root /usr/share/nginx/html/<tenant>/spa)
    • admin (Static Web Root /usr/share/nginx/html/<tenant>/admin)
  • ขอใบรับรอง SSL (Let's Encrypt Certbot) ให้ครบทุก Subdomain
  • Reload Nginx: docker exec -it nginx nginx -s reload

Step 6: Automated Post-Receive Hook & Git Remote

  • สร้าง Bare Git Repo: /home/ti/git/<tenant>.git
  • ตั้งค่า Hook hooks/post-receive พร้อมสิทธิ์ chmod +x
  • เพิ่ม Git Remote ที่เครื่อง Local:
    git remote add demo-<tenant> ti@kittisak.com:/home/ti/git/<tenant>.git
    

3. Smoke Test Verification (ต้องผ่านครบทุกข้อก่อนส่งมอบงาน)

ห้ามประกาศว่าเสร็จงานจนกว่าจะรันคำสั่งทดสอบครบทั้ง 5 ข้อนี้:

  1. ทดสอบ Website SSR:

    curl -I https://<tenant>.kittisak.com/th
    # ต้องได้ HTTP 200 OK
    
  2. ทดสอบ Backend API Status:

    curl -I https://api.<tenant>.kittisak.com/api/categories
    # ต้องได้ HTTP 200 OK
    
  3. ทดสอบ Static SPA & Admin:

    curl -I https://spa.<tenant>.kittisak.com
    curl -I https://admin.<tenant>.kittisak.com
    # ต้องได้ HTTP 200 OK
    
  4. ทดสอบ Admin Login API (CRITICAL):

    curl -X POST https://api.<tenant>.kittisak.com/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"username":"admin","password":"homaroma123"}'
    # ผลลัพธ์ต้องเป็น: {"success":true,"token":"...","user":{"username":"admin"}}
    
  5. ตรวจสอบตาราง User ในฐานข้อมูล:

    • ตาราง User ต้องมีอย่างน้อย 1 คน
    • ข้อมูลสินค้าในตาราง Product ต้องมากกว่า 0