7.6 KiB
7.6 KiB
สรุปปัญหา ข้อผิดพลาด และ Checklist การสร้าง Tenant / Subdomain ใหม่
(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 จึงหาชื่อผู้ใช้ไม่พบ และส่ง Error401 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, ...)
- Backend API Port (เช่น
- ผูก 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 ในตารางจริง:
(ต้องเห็น user
docker exec -i arokro_postgres psql -U postgres -d <tenant>_db -c "SELECT id, username, role FROM \"User\";"admin/ roleADMINจำนวน 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 ข้อนี้:
-
ทดสอบ Website SSR:
curl -I https://<tenant>.kittisak.com/th # ต้องได้ HTTP 200 OK -
ทดสอบ Backend API Status:
curl -I https://api.<tenant>.kittisak.com/api/categories # ต้องได้ HTTP 200 OK -
ทดสอบ Static SPA & Admin:
curl -I https://spa.<tenant>.kittisak.com curl -I https://admin.<tenant>.kittisak.com # ต้องได้ HTTP 200 OK -
ทดสอบ 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"}} -
ตรวจสอบตาราง User ในฐานข้อมูล:
- ตาราง
Userต้องมีอย่างน้อย 1 คน - ข้อมูลสินค้าในตาราง
Productต้องมากกว่า 0
- ตาราง