feat(ops): serve Happy QA to the team over a Cloudflare tunnel
ปุ่มเดียวเปิด/ปิดเว็บให้คนนอกเข้ามาเทส: OrbStack รัน web (Next standalone) + cloudflared ที่ ops/compose.yml แล้ว ops/serve.sh คุมการเปิด-ปิดกับ .env.local ที่เดียว โดยที่ token ไม่หลุดออกจากไฟล์นั้น
สิ่งที่กัดมาแล้วและถูกล็อกไว้ในไฟล์เหล่านี้:
- cloudflared ใช้ network_mode: service:web เพราะ ingress ผูกกับ localhost:3078 ถ้าอยู่คนละ namespace localhost จะกลายเป็นตัว cloudflared เอง แล้วได้ 502
- container ฟัง HOSTNAME=:: (dual-stack) เพราะ cloudflared แปลง localhost เป็น ::1 ก่อนแล้วไม่ถอยไปลอง IPv4
- image เป็น node:22-slim ไม่ใช่ alpine — Prisma 7 ต้องการ openssl/glibc
- NEXT_DIST_DIR ให้ production build อยู่คนละโฟลเดอร์กับ next dev ไม่งั้นทับกันพังทั้งคู่
- outputFileTracingRoot ต้องชี้ root ของ monorepo ไม่งั้น tracer หา @happy-qa/board กับ @prisma/client ที่ถูก hoist ขึ้นไปไม่เจอ
ops/.env ถูก .gitignore ตามกฎ .env* ของ repo ทั้งที่ไม่มีความลับ จึงมี ops/.env.example ไว้ให้คัดลอก
Co-Authored-By: Claude Opus 5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_013k8ukm9qwQrfZR5aGXdwHV