เผยแพร่กรกฎาคม 2026 · บันทึกโครงสร้างพื้นฐานจาก 3DN
DutchBud คือแอปธนาคารส่วนตัวของเรา — แอป Android ที่สื่อสารกับ bank.dutchie.org ผ่าน JSON API การพาแอปจาก “ใช้ได้บนแล็ปท็อป” ไปเป็น “ใช้ได้บนมือถือผ่าน WireGuard ตอนตีสอง” ต้องแตะ DNS, pipeline deploy OTAP, การแยก API จาก Laravel ไป Go อย่างตั้งใจ และชุด regression test ที่เปรียบเทียบทุก release บน Acceptatie กับข้อมูลในรูปแบบ production โพสต์นี้คือทัวร์ครับ

ตั้งค่า DutchBud แบบ end-to-end
สแตกตั้งใจให้น่าเบื่อ — และนั่นเป็นคำชม:
- Android client — แอป Kotlin ใช้ token auth กับ endpoint
/api/* - Laravel web app — ยังให้ UI บราวเซอร์ migrations และสคริปต์ deploy OTAP ใน web root แยกตาม environment
- Go
bank-api— JSON API production บน application server คู่กันเป็น systemd service nginx ส่ง/api/ผ่าน HAProxy ไป Go ส่วน Laravel ดูแลส่วนที่เหลือ - การเข้าถึง edge — client WireGuard resolve ชื่อภายในผ่าน authoritative DNS ของเรา
bank.dutchie.orgไปถึง DMZ front ประเทศไทยบนเครือข่ายส่วนตัว
การทดสอบบนมือถือช่วงแรกเจอกับดัก ops คลาสสิก: BIND ที่หลุดมาบน gateway ตอบ DNS พร้อมพฤติกรรม AAAA เสีย ทำให้ resolution ของ WireGuard ดูโอเคจนกว่าจะไม่โอเค ชี้ client ไป resolver ที่ถูกต้อง หยุดบริการที่หลุดมา และแก้ port forwarding ทำให้ resolution คาดเดาได้อีกครั้ง login 422 กลายเป็นปัญหา reachability ไม่ใช่รหัสผ่านผิด — พอ DNS และ routing ซื่อสัตย์ แอปก็กลับมา

ทำไมย้าย API จาก Laravel ไป Go
Laravel ยอดเยี่ยมสำหรับความเร็วในการทำ product แต่ไม่ค่อยยอดเยี่ยมเมื่อทุก API call จ่ายภาษี bootstrap framework PHP เต็มๆ บน path ที่แอป Android เรียกหลายสิบครั้งต่อ session เราวัดบน host เดียวกันก่อนตัดสินใจ:
- Bootstrap framework Laravel อย่างเดียว: ~100 ms ก่อน controller ทำงาน
- Go
GET /api/bank-accounts: ~12 ms บน localhost - Go
GET /api/payments?page=1: ~150 ms (ผูกกับ database ไม่ใช่ framework) - Go
POST /api/login: ~280 ms — bcrypt ยังครอง login ชนะอยู่ที่อื่น
เกณฑ์ตัดสินเป็นเรื่องปฏิบัติ ไม่ใช่ศาสนา:
- Latency บน JSON path ร้อน — บัญชีและ list endpoint ต้องรู้สึกทันทีบนมือถือ
- memory footprint — Go binary เล็กต่อ node ชนะ PHP-FPM pool สำหรับ read-heavy API
- ความเรียบง่ายในการ operate — binary เดียว structured logging config บน API host
- เก็บ Laravel ตรงที่เก่ง — Blade UI Eloquent migrations playbook OTAP เดิมไม่เปลี่ยน
/api/ Laravel บนพื้นผิวเว็บOTAP CI — จาก push dev ถึงประตู production
แอป bank เป็น OTAP pilot ของเรา GitLab CI บน dedicated runner deploy ตาม branch:
- dev → Ontwikkel แล้ว fast-forward tst → Test
- commit ต้องมี
Refs #Npipeline โพสต์ “Ready for Test” บน issue ที่เชื่อม - acc → deploy Acceptatie แบบ manual หลังลูกค้าอนุมัติบน Test
- master → Productie แบบ manual
Deploy คือ SSH git checkout ที่แข็งแกร่งบน application host: fetch hard reset ไป SHA ของ pipeline แก้สิทธิ์ รัน environment setup ถ้ามี ไม่มีปริศนา rsync — แค่ความจริงของ git ทุก stage
accRegression test บนรูปแบบ production จริง
Acceptatie ไม่ใช่ฐานข้อมูลของเล่น หลัง deploy:acceptatie แบบ manual CI รัน:
- sync:prod-db-to-acc — คัดลอกข้อมูล production ไป acceptance database พร้อม sync receipt storage
- migrate:acc — ใช้ Laravel migrations ที่ค้างบน ACC
- regression:check — ยิง ACC API สดและเทียบกับ baseline ที่ commit แล้ว
ชุดทดสอบอยู่ใน bank-api repository สี่ scenario — login, bank-accounts, budget-posts, payments หน้า 1 — แต่ละอัน 20 iteration แบบ sequential (~6 วินาทีรวม) ทุก scenario บันทึก HTTP status shape hash ของ JSON payload (โครงสร้างและ key ไม่ใช่ค่าที่เปลี่ยน) และ p95 latency baseline เริ่มต้นหลัง prod sync: login p95 598 ms bank-accounts 116 ms budget-posts 184 ms payments 178 ms กับ 58 payments และ 3 accounts
check job ทำให้ pipeline fail ถ้า shape เปลี่ยนหรือ p95 เกิน baseline × tolerance (1.25× ค่าเริ่มต้น 1.5× สำหรับ login) ต้องการ baseline ใหม่หลังเปลี่ยน API โดยตั้งใจ? รัน regression:capture แบบ manual แล้ว commit baseline ที่อัปเดตใน bank-api repo ผลลัพธ์อยู่ใน GitLab job log — ไม่ต้องพึ่ง SaaS ภายนอก
สิ่งที่เราเรียนรู้
แอปมือถือลงโทษบาปโครงสร้างพื้นฐานเล็กๆ DNS ที่เกือบใช้ได้แย่กว่า DNS ที่ล้มเหลวชัดเจน แยก API runtime ได้เมื่อขอบเขตคือ nginx และสัญญาคือ JSON OTAP ได้รับความไว้วางใจเมื่อ Test กับ Acceptatie ต่างกันเชิงกล — promotion แบบ manual บวก regression อัตโนมัติบนข้อมูล prod-shaped คือความต่างนั้น
DutchBud คือซอฟต์แวร์ส่วนตัวบนรางมืออาชีพ ครั้งหน้าที่หน้าบัญชีสีเขียวโหลดภายในหนึ่งวินาทีผ่าน WireGuard นั่นคือ Go, PowerDNS, GitLab CI และไฟล์ baseline ที่บอกว่า “ยังรูปแบบเดียวกับเมื่อวาน”
มีคำถามเกี่ยวกับโครงสร้างพื้นฐานหรือแนวทาง hosting ของเรา? ติดต่อเรา
ใส่ความเห็น