บทความที่แล้วผมบอกว่า [Docker + VPS ง่ายกว่าที่คิด](/knowledge/docker-vps-for-sme) — วันนี้จะเล่าให้ฟังว่า ถ้าไม่ระวัง มันพังได้ยังไง
Server หายไป
วันนั้นเป็น deploy ปกติ ไม่มีอะไรพิเศษ pull code ใหม่ รันคำสั่งที่รันมาหลายสิบครั้งแล้ว:
Build เริ่มต้น layer ต่อ layer ผ่านไปประมาณ 40 วินาที แล้ว terminal ก็ค้าง
ไม่มี error ไม่มี output ใหม่ แค่หยุด
รอ 2 นาที ยังค้างอยู่ ลอง Ctrl+C แล้ว SSH เข้าใหม่ — connection timeout
ลอง ping:
Server หายไปจากโลก 30 นาที กว่าจะ reboot กลับมาได้
ทำไม Build Cache เป็นระเบิดเวลา
ทุกครั้งที่รัน `docker compose build` Docker จะสร้าง layer cache เพื่อให้ build ครั้งต่อไปเร็วขึ้น — นั่นคือฟีเจอร์ที่ดี แต่ cache เหล่านี้สะสมอยู่บน disk และ Docker ไม่ลบออกเอง
deploy ครั้งที่ 1 → cache 2GB
deploy ครั้งที่ 5 → cache 8GB
deploy ครั้งที่ 10 → cache 18GB
deploy ครั้งที่ 30 → cache 53GB
บน MacBook Pro ที่มี SSD 512GB เรื่องนี้ไม่เป็นปัญหา เราไม่รู้สึกอะไร แต่บน VPS 4GB RAM / 75GB SSD ที่รัน production — นี่คือระเบิดเวลา
สถานะ disk ก่อน crash:
สถานะ RAM ณ เวลาปกติ:
เหลือ RAM แค่ 1.5GB — และ Docker build ใช้มากกว่านั้น
ทำไมถึง Crash
ปัญหาไม่ได้มาจาก disk เต็ม — แต่มาจาก RAM ไม่พอตอน build
เมื่อรัน `docker compose build` ขณะที่ app กำลังรันอยู่ Docker จะโหลด build context เข้า memory, compile TypeScript, รัน Next.js build process — ทั้งหมดนี้ต้องการ RAM เพิ่มอีก 1.5GB ขึ้นไป
Timeline ของ crash:
OOM Killer (Out-of-Memory Killer) คือกลไกป้องกันตัวของ Linux kernel — เมื่อ RAM ทั้งระบบเหลือใกล้ศูนย์ kernel จะเลือก process ที่ใช้ memory มากที่สุดแล้วบังคับปิด (kill) ทันทีเพื่อเอา RAM คืนให้ระบบทำงานต่อได้ ปัญหาคือ kernel ไม่รู้ว่า process ไหนสำคัญกว่ากัน — มันอาจ kill database แทน build process ก็ได้ ผลคือ app ที่ต่อ DB อยู่พังตาม และถ้า kernel เองก็ไม่เหลือ RAM พอจัดการ ระบบทั้งหมดก็ freeze
วิธีแก้: 3 ทางเลือกสำหรับ Push Schema
หนึ่งในสาเหตุที่ build ใช้ RAM มากคือ pattern การ migrate database — หลายคนทำ `docker compose build` เพื่อสร้าง image ใหม่แล้วรัน migration ใน container นั้น วิธีนี้กิน RAM มากกว่าจำเป็น
วิธีที่ดีที่สุด — Docker Exec:
ความต่างคือ `exec` ใช้ container ที่มีอยู่แล้ว ไม่ต้อง build ใหม่ ไม่ต้อง load image ใหม่ ใช้ RAM แค่สำหรับ command นั้นจริงๆ
Safe Deploy Workflow — 6 Phases
หลังจากเหตุการณ์นั้น ผมเขียน deploy workflow ใหม่ที่มี cleanup เป็น phase บังคับ:
Phase 2 สำคัญมาก — ไม่ใช่แค่ทำตอน disk เกือบเต็ม แต่ต้องทำ ทุก deploy เพราะ cache สะสมทีละน้อยและเราจะไม่รู้สึกตัวจนถึงจุดที่ระเบิด
Docker Cleanup — อะไรลบได้ อะไรห้ามแตะ
`--volumes` จะลบ database data, upload files, persistent storage ทั้งหมด — ถ้ายังไม่มี backup ที่ verified แล้วรันคำสั่งนี้บน production คือ data loss ทันที
สำหรับ routine cleanup ที่ปลอดภัย:
Resource Budget — คิดเหมือนงบบ้าน
VPS 4GB RAM / 75GB SSD ต้องวางแผนการใช้ resources เหมือนงบก่อสร้าง — รู้ว่าแต่ละส่วนใช้เท่าไหร่ และเหลือ headroom เท่าไหร่สำหรับ spike
RAM Budget:
ถ้า RAM ที่ build ใช้ชั่วคราวเกิน RAM ที่เหลืออยู่ แม้แค่ครั้งเดียว — OOM Killer ก็ถูก trigger
วิธีแก้มี 2 ทาง:
1. ลด RAM ที่ build ใช้ (ใช้ docker exec แทน build สำหรับ migration)
2. เพิ่ม swap (สำรอง 2GB บน disk เป็น virtual RAM) — ช้ากว่า RAM จริงแต่ป้องกัน crash
Disk Budget:
เหลือ 55GB สำหรับ growth — แต่ถ้าไม่ล้าง build cache มันจะกินส่วนนี้ทั้งหมดใน 30 deploys
สรุป — กฎ 5 ข้อที่ต้องจำ
1. Prune ก่อน Build เสมอ
ทำเป็น habit ทุกครั้งก่อน deploy ไม่ว่า disk จะเหลือเท่าไหร่
2. ใช้ docker exec แทน build สำหรับ migration
ประหยัด RAM 1.4GB ต่อครั้ง บน VPS 4GB นี่คือความต่างระหว่างรอดกับพัง
3. รู้ขีดจำกัด server ของตัวเอง
ถ้า RAM เหลือน้อยกว่า 1.5GB หรือ disk เหลือน้อยกว่า 15GB — cleanup ก่อน แล้วค่อย deploy
4. ห้ามใช้ --volumes บน production
`--volumes` ลบข้อมูลจริง ถ้ารันผิด machine หรือผิดเวลา — data หาย ไม่มีทางกลับ
5. มี recovery plan ก่อน deploy ทุกครั้ง
ก่อน deploy ต้องตอบได้ว่า: "ถ้า deploy แล้วพัง rollback ยังไง?"
- Database snapshot ล่าสุดอยู่ที่ไหน
- ใช้เวลา restore นานแค่ไหน
- มี direct access เข้า server ถ้า SSH ไม่ได้ (hosting provider ส่วนใหญ่มี rescue console หรือ VNC)
ทุกอย่างที่เล่ามาเกิดจาก deploy ปกติที่ทำมาหลายสิบครั้งแล้ว — ต่างกันแค่ว่าครั้งนี้ cache สะสมมากพอที่จะทำให้ระบบไม่มีที่หายใจเวลา build
Docker ยังเป็นเครื่องมือที่ดีที่สุดสำหรับ deploy บน VPS แต่ต้องเข้าใจว่ามันทำงานยังไงและมีขีดจำกัดที่ไหน
ถ้าสนใจ deploy workflow แบบเต็ม หรืออยากคุยเรื่อง resource planning สำหรับ VPS ขนาดเล็ก — ทักมาได้เลยครับ