Deploy ไป Cloudflare Workers

View raw
On this page

คู่มือฉบับเต็มทีละคำสั่ง (TH + EN) คือ DEPLOY.md หน้านี้ไม่คัดลอกซ้ำ แต่สรุปกระบวนการ เหตุผล และ checklist ที่ต้องทำทุกครั้ง

นโยบาย (ต้องอ่านก่อน)#

  • การ deploy ทุกครั้งต้องได้รับอนุมัติจากมนุษย์ ระบุบัญชี ชื่อ Worker และขอบเขตอย่างชัดเจน
  • deploy เฉพาะ Worker ใหม่ชื่อ nvx-stack-builder บน workers.dev เท่านั้น ห้ามเพิ่ม routes, custom domain, DNS
  • ห้ามแก้หรือลบ Worker/resource อื่น ในบัญชี (เช่น agents-sdk-space, agent-starter, mcp-worker ฯลฯ) และห้ามแตะ zone agents-sdk.space
  • ห้าม git push ถ้าไม่ได้รับคำสั่ง ห้ามพิมพ์ secret

ขั้นตอนโดยสรุป#

  1. ตรวจโค้ด: npm run lint && npm run typecheck && npm test && npm run docs:check && npm run cf:build
  2. ตั้งตัวแปร: CLOUDFLARE_API_TOKEN (เฉพาะ token), CLOUDFLARE_ACCOUNT_ID (บัญชี production 2d92bd5b25768fa9093d6adc0a8887fc, devstack.bid, workers.dev examplessdk; บัญชีเดิม v0.3.0 f70d35188a3c56b9781538c73a86e04e) ถ้าใช้ token หลายบัญชีบนเครื่องเดียว ให้ส่งเฉพาะคำสั่ง เช่น CLOUDFLARE_API_TOKEN="$TOKEN_X" CLOUDFLARE_ACCOUNT_ID=<id> npx wrangler ... แทนการ export ค้างไว้
  3. ตรวจชื่อว่าง/เป็นของเรา: npx wrangler deployments list --name nvx-stack-builder ถ้าชื่อถูกใช้โดย Worker อื่นที่ไม่ใช่ของเรา เปลี่ยน name และ services[0].service ใน wrangler.jsonc เป็น nvx-stack-builder-staging
  4. Deploy: npm run deploy (= build + opennextjs-cloudflare deploy) ครั้งแรกจะสร้าง Worker และ rate-limit bindings
  5. Secret: printenv OPENAI_API_KEY | npx wrangler secret put OPENAI_API_KEY
  6. บันทึก version id จากผลลัพธ์ (ใช้ rollback)
  7. Smoke test (ด้านล่าง)
  8. อัปเดตสถานะใน DEPLOY.md และ CHANGELOG

Smoke test หลัง deploy#

bash
BASE=https://devstack.bid   # production; สำรอง https://nvx-stack-builder.examplessdk.workers.dev; v0.3.0 เดิม: https://nvx-stack-builder.agen-sdk-work.workers.dev
for p in / /templates /templates/nextjs-dashboard /builder /design; do curl -s -o /dev/null -w "$p %{http_code}\n" $BASE$p; done
curl -s -o /dev/null -w "404 check %{http_code}\n" $BASE/templates/does-not-exist     # ต้อง 404
curl -sI $BASE/ | grep -iE 'strict-transport|content-security|x-frame'
curl -s $BASE/api/plan                                                               # serverKeyConfigured: true
curl -s -X POST $BASE/api/plan -H 'content-type: application/json' \
  -d '{"prompt":"แดชบอร์ดยอดขาย Next.js","lang":"th"}' | head -c 300                  # source: openai

ทดสอบ rate limit: ส่ง POST แบบ mode: "fallback" 21 ครั้งใน 1 นาทีบน connection เดียว (curl --next หรือ keep-alive) ครั้งที่ 21 ต้องได้ 429 พร้อม Retry-After: 60 หมายเหตุ: ถ้าเครื่องทดสอบออกเน็ตด้วย IPv6 ที่หมุนทุก connection (เช่น WARP) ให้ทดสอบบน connection เดียว

สิ่งที่การ deploy สร้าง#

  • Worker script nvx-stack-builder + static assets
  • rate-limit bindings NVX_PLAN_LIMITER (4712), NVX_PLAN_AI_LIMITER (4711) — เป็น config ไม่ใช่ resource แยก
  • secret OPENAI_API_KEY
  • ไม่สร้าง KV, R2, D1, route, DNS record

ค่าใช้จ่าย#

Workers มี free tier; ค่าใช้จ่ายหลักคือ OpenAI ซึ่งถูกจำกัดด้วย AI limiter (5/นาที/IP) และ OPENAI_MAX_OUTPUT_TOKENS ดู rate-limits-cost.md

ต่อไป#

rollback.md, monitoring.md, custom-domain.md

บันทึก deploy v0.5.0 (11 ต.ค. 2026)#

  • ตรวจบัญชีก่อน: ใช้ GET แบบอ่านอย่างเดียว (/accounts/<id>/workers/scripts และ /workers/subdomain) เพราะ wrangler ไม่มีคำสั่ง list Worker ผลที่ได้: มี Worker เดิม 1 ตัว (odd-violet-5e66, ไม่แตะ), subdomain space6 ลงทะเบียนไว้แล้ว และชื่อ nvx-stack-builder ยังว่าง จึงไม่ต้องใช้ -staging
  • deploy: opennextjs-cloudflare deploy จาก build ที่ผ่าน preview test แล้ว ได้ version 107ab78e-2cdd-4159-95e7-e8fcb89130aa (08:47 ICT) แล้วตั้ง secret ผ่าน stdin ได้ version d369f2b6-863a-4e44-8f9e-b5551e18361a
  • smoke test: ผ่านทุกข้อ (หน้า, 404, headers, asset แบรนด์, AI ภาษาไทยได้ source: "openai", 429 พร้อม Retry-After: 60) ภาพหน้าจอจากเว็บจริงอยู่ที่ screenshots/v0.5/live-*
  • ข้อสังเกต: ตัวนับ rate limit เป็นแบบ eventually consistent จึงอาจได้ 200 เกิน limit 1 ครั้ง และ request ที่เปิด connection ใหม่จาก box นี้อาจออกจาก IP คนละตัว ให้ทดสอบ rate limit บน connection เดียว (curl --next)

บันทึก deploy v0.5.1: โดเมน devstack.bid (11 ต.ค. 2026)#

  • ตรวจ token: token DEVSTACK อยู่บัญชีเดียวกันแต่ไม่มีสิทธิ์ Workers Scripts จึงใช้ token EXAMPLESSDK (Workers Scripts: Edit + Zone: Read) ผูกโดเมนผ่าน PUT /accounts/{id}/workers/domains ได้ทั้ง devstack.bid และ www.devstack.bid และ Cloudflare สร้าง AAAA 100:: แบบ proxied ให้เอง
  • โค้ด: routes (custom_domain) ใน wrangler.jsonc, redirect www → apex ใน next.config.ts, metadataBase = devstack.bid, HSTS ไม่มี includeSubDomains แล้ว deploy ได้ version 671b6b3b-1074-40cb-84b0-0df2681b69ce (09:15 ICT)
  • ใบรับรอง: ออกทันที (Google Trust Services, SAN devstack.bid + *.devstack.bid)
  • smoke test บนโดเมน:
    • ทุกหน้าได้ 200 และ 404 จริง; www ตอบ 308 พร้อมคง path/query
    • headers ครบ (HSTS max-age=31536000); og:image เป็น https://devstack.bid/opengraph-image.png… และโหลดได้
    • AI ภาษาไทยได้ source: "openai" (35 วินาที) และ 429 พร้อม Retry-After: 60 หลัง 20 ครั้ง
    • มาสคอตขยับและตามองตามเมาส์
    • ภาพหน้าจออยู่ที่ screenshots/v0.5/domain-*
  • ข้อสังเกต:
    • prompt ที่ซับซ้อนกว่า 1 ครั้งเกิน OPENAI_TIMEOUT_MS (75 วินาที) จึงได้ offline planner ซึ่งเป็นพฤติกรรมที่ออกแบบไว้
    • Cloudflare Web Analytics แทรก beacon ที่ CSP บล็อก ดู custom-domain.md

บันทึก deploy v0.6.0: docs ในแอป + signature (11 ต.ค. 2026)#

  • ที่มา: merge feat/docs-site เข้า main แล้ว bump เป็น 0.6.0; lint, typecheck, tests, docs:check และ cf:build ผ่านทั้งหมดก่อน deploy
  • deploy: ใช้ token EXAMPLESSDK; ได้ version 7ddd9404-a31f-4e31-8460-82b3b90c7d0e (11:18 ICT) ขนาด upload 9467.97 KiB (gzip 1810.44 KiB); custom domain devstack.bid + www ยังอยู่ครบ
  • ตรวจบนเว็บจริง:
    • ทุกหน้า รวม /docs และหน้าย่อย ได้ 200; slug ที่ไม่มีได้ 404 จริง
    • raw .md ทั้ง 43 ไฟล์ตรงกับต้นฉบับทุก byte (text/markdown, ACAO *); manifest ก็ตรง
    • /llms.txt มีลิงก์ 43 รายการ; /llms-full.txt ขนาด 336 KB
    • headers ครบ; www ตอบ 308
    • AI ภาษาไทยได้ source: "openai"
    • signature อยู่ใน footer ทุกหน้า; touch glow ทำงาน
    • ภาพหน้าจออยู่ที่ screenshots/v0.6/live-*
  • ข้อสังเกต: console มี error จาก CSP บล็อก static.cloudflareinsights.com/beacon.min.js (Web Analytics ที่ Cloudflare ฉีดเข้ามา) ไม่มีผลกับการทำงาน; จะเปิดใน CSP หรือปิด Web Analytics ต้องให้ผู้ใช้ตัดสินใจ
  • rollback: 671b6b3b-1074-40cb-84b0-0df2681b69ce (v0.5.1)

บันทึก deploy: เพิ่ม D1 binding (11 ต.ค. 2026)#

  • สร้าง D1 nvx-db (3ee9bbab-06b5-49da-b175-5f7162ad5086, WNAM) แล้ว apply migration 0001 และ 0002 บน remote (d1-database.md)
  • deploy จาก branch feat/d1-chat-schema หลังจาก lint, typecheck, tests, docs:check และ cf:build ผ่าน; ได้ version 450890b7-5432-4795-afbc-1c7ebd241bff; binding env.DB (nvx-db); custom domain ยังอยู่ครบ
  • ตรวจบนเว็บจริง:
    • ทุกหน้าได้ 200 และ 404 จริง
    • raw .md ทั้ง 46 ไฟล์ตรงกับต้นฉบับทุก byte
    • GET /api/plan ปกติ; www ตอบ 308
    • หน้า docs ใหม่และ ER diagram โหลดได้ ไม่มี console error นอกจาก beacon ของ Web Analytics
  • rollback: 7ddd9404-a31f-4e31-8460-82b3b90c7d0e (v0.6.0)

Source: docs/operations/deploy-cloudflare.md · /docs/operations/deploy-cloudflare.md