จัดการ RAM ของ Docker (Windows / WSL2)
อาการที่เจอ
- เปิด Docker Desktop แล้ว process
vmmem/vmmemWSLกิน RAM เกือบทั้งเครื่อง - ปิด container หมดแล้ว RAM ก็ยังไม่คืน
- build ใน container ตายเงียบ ๆ ไม่มี error ชัดเจน (exit code
137= ถูก OOM killer ฆ่า) - build ช้าผิดปกติ เหมือนค้าง ทั้งที่ CPU ไม่เต็ม
สาเหตุ: บน Windows Docker Desktop รันบน WSL2 ซึ่ง VM ตัวนี้จะขยาย RAM ไปเรื่อย ๆ จนถึงเพดาน default (สูงสุด ~50-80% ของ RAM เครื่อง) และไม่คืนให้ Windows
วิธีแก้: ไฟล์ .wslconfig
สร้าง/แก้ไฟล์ C:\Users\<username>\.wslconfig (พิมพ์ %USERPROFILE% ใน File Explorer เพื่อไปที่โฟลเดอร์)
[wsl2]
memory=16GB
processors=16
swap=8GB
autoMemoryReclaim=gradual| ค่า | ความหมาย |
|---|---|
memory | เพดาน RAM ที่ WSL2 (และ Docker ทั้งหมด) ใช้ได้ |
processors | จำนวน CPU core ที่ให้ WSL2 |
swap | swap file ของ WSL2 — กัน OOM ตอน build หนัก |
autoMemoryReclaim=gradual | คืน RAM ที่ไม่ได้ใช้ให้ Windows อัตโนมัติ (ค่านี้แก้อาการ “ปิด container แล้ว RAM ไม่คืน”) |
หลังแก้ไฟล์ ต้อง restart WSL:
wsl --shutdownแล้วเปิด Docker Desktop ใหม่ ค่าจึงมีผล (แก้ไฟล์เฉย ๆ ไม่พอ)
เลือกค่าเท่าไหร่ดี
memory≈ 50-75% ของ RAM เครื่อง — เหลือให้ Windows + IDE + browser อย่างน้อย 8GB- เครื่อง 32GB →
memory=16GBถึง20GB - เครื่อง 16GB →
memory=8GBถึง10GB
- เครื่อง 32GB →
processorsตั้งเท่าจำนวน core จริงได้ ไม่ใช่ตัวที่ทำให้เครื่องอืด (RAM คือตัวปัญหา)swapเผื่อไว้ครึ่งหนึ่งของmemory— ช้ากว่า RAM แต่ดีกว่าโดน OOM kill
ตรวจสอบว่าค่ามีผลจริง
wsl -- free -h # ดูว่า total ตรงกับที่ตั้งไว้หรือดู process vmmemWSL ใน Task Manager ว่าเพดานหยุดตามที่ตั้ง
จำกัด RAM ราย container
.wslconfig คุมภาพรวม ถ้าอยากกันไม่ให้ container ตัวเดียวกินหมด:
docker run -m 4g --memory-swap 6g <image>ใน docker-compose.yml:
services:
app:
mem_limit: 4gกับดักที่เจอบ่อย
1. Node.js heap ไม่เท่ากับ RAM ของ container
Node จำกัด heap ตัวเองแยกต่างหาก (default ~4GB) — เพิ่ม RAM ให้ container อย่างเดียวไม่พอ
ถ้า build/test ตายด้วย JavaScript heap out of memory ต้องเพิ่มทั้งสองฝั่ง:
ENV NODE_OPTIONS=--max-old-space-size=8192และ container ต้องมี RAM มากกว่าค่านี้ ไม่งั้นจะโดน OOM kill (exit 137) แทน
2. เปิด container หลายตัวพร้อมกันตอน build ใหญ่
build หนัก ๆ มักติดที่ การแย่ง CPU/disk ไม่ใช่ compute — มี dev server + database + service อื่น รันอยู่ด้วย build จะช้าลงหลายเท่าจนดูเหมือนค้าง ปิดตัวที่ไม่ใช้ก่อน build:
docker ps -q | xargs docker stop3. Disk เต็มจาก volume ที่ไม่ได้ลบ
คนละเรื่องกับ RAM แต่มาคู่กัน — volume ที่ไม่มีใครใช้ไม่ถูกลบเอง สะสมได้เป็นร้อย GB
docker system df # ดูขนาดรวม (ช้ามากถ้า volume เยอะ)
docker volume ls
docker volume rm <name> # ลบทีละตัวตามชื่อ⚠️ ระวัง
docker volume pruneและdocker image prune -a— ถ้า stack ไม่ได้รันอยู่ ตอนนั้น volume/image ที่ยังใช้อยู่จะถูกนับเป็น “unused” แล้วโดนลบไปด้วย ให้ลบทีละชื่อจะปลอดภัยกว่า