เรียนรู้วิธีตั้งค่า swap memory บน Hetzner Cloud volume เพื่อป้องกัน out-of-memory crash ระหว่าง build, deploy และงานหนักบน Ubuntu server

ถ้าเคยรัน pnpm build หรือ npm run build บน cloud server ขนาดเล็ก แล้วเจอ OOM (Out of Memory) error คุณจะเข้าใจความเจ็บปวดนี้ดี กระบวนการ build กิน RAM ทั้งหมด Linux kernel ก็ kill process ทิ้ง แล้วคุณก็เหลือแค่ error Command failed with signal "SIGKILL"
ทางแก้? Swap memory — และที่ที่ดีที่สุดในการวาง swap บน Hetzner Cloud คือบน ไม่ใช่ root disk
Hetzner Cloud server ส่วนใหญ่มี root disk ขนาดค่อนข้างเล็ก (20-80GB ขึ้นอยู่กับแพลน) การใช้ swap บน root disk มีปัญหาสองอย่าง:
Hetzner Cloud volumes เป็น block storage แยกต่างหาก ที่เชื่อมต่อผ่าน network ราคาถูก (ประมาณ €0.052/GB/เดือน) และปรับขนาดได้อิสระ การวาง swap บน volume ช่วยแยก swap I/O ออกจาก disk ของแอปพลิเคชัน
ถ้ายังไม่มี volume ให้สร้างใน Hetzner Cloud Console:
หลังสร้างเสร็จ volume จะปรากฏเป็น block device ตรวจสอบว่าเป็น device ไหน:
# แสดง block devices ทั้งหมด
lsblk
# Output ทั่วไป:
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 150G 0 disk
# └─sda1 8:1 0 150G 0 part /
# sdb 8:16 0 40G 0 diskในตัวอย่างนี้ sdb คือ volume ของเรา (40GB)
ถ้าเป็น volume ใหม่ ให้ format ด้วย ext4:
# Format volume (ระวัง: จะลบข้อมูลทั้งหมด)
sudo mkfs.ext4 /dev/sdb
# สร้าง mount point
sudo mkdir -p /mnt/volume
# Mount volume
sudo mount /dev/sdb /mnt/volumeทำให้ mount อัตโนมัติทุกครั้งที่ reboot โดยเพิ่มใน /etc/fstab:
# ดู UUID ของ volume
sudo blkid /dev/sdb
# Output: /dev/sdb: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="ext4"
# เพิ่มใน fstab (ใส่ UUID จากด้านบน)
echo 'UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/volume ext4 defaults 0 2' | sudo tee -a /etc/fstabสร้าง swap file บน volume ที่ mount แล้ว สำหรับ server ที่มี RAM 8-16GB แนะนำ swap 4-8GB:
# สร้าง swap file ขนาด 4GB
sudo fallocate -l 4G /mnt/volume/swapfile
# ตั้ง permission ให้ถูกต้อง (root เท่านั้นที่อ่าน/เขียนได้)
sudo chmod 600 /mnt/volume/swapfile
# Format เป็น swap
sudo mkswap /mnt/volume/swapfileOutput ที่คาดหวัง:
Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
no label, UUID=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
# เปิดใช้ swap file
sudo swapon /mnt/volume/swapfile
# ตรวจสอบว่าทำงานอยู่
free -hจะเห็นผลลัพธ์ประมาณนี้:
total used free shared buff/cache available
Mem: 15Gi 8.2Gi 1.1Gi 256Mi 6.5Gi 7.0Gi
Swap: 4.0Gi 0B 4.0Gi
เพิ่ม swap file ใน /etc/fstab เพื่อให้เปิดใช้อัตโนมัติเมื่อ boot:
echo '/mnt/volume/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabตรวจสอบว่า fstab ถูกต้อง:
# ทดสอบ fstab โดยไม่ต้อง reboot
sudo mount -a
# ตรวจสอบ swap ที่ active อยู่
swapon --showค่า swappiness ควบคุมว่า Linux จะใช้ swap มากแค่ไหน ค่าเริ่มต้นคือ 60 แต่สำหรับ server ที่รัน Node.js builds ค่าที่ต่ำกว่าจะดีกว่า:
# ดูค่า swappiness ปัจจุบัน
cat /proc/sys/vm/swappiness
# ตั้งเป็น 10 (ใช้ RAM ก่อน swap เมื่อจำเป็นเท่านั้น)
sudo sysctl vm.swappiness=10
# ทำให้ถาวร
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.confอธิบายค่า swappiness:
| ค่า | พฤติกรรม |
|---|---|
| 0 | Swap เฉพาะเมื่อจะเกิด OOM killer |
| 10 | Swap อย่างไม่เต็มใจ (แนะนำสำหรับ server) |
| 60 | ค่าเริ่มต้น — สมดุลระหว่าง RAM กับ swap |
| 100 | Swap อย่างจริงจังไปที่ disk |
ค่านี้ควบคุมว่า kernel จะคืน memory ที่ใช้สำหรับ directory และ inode caches เร็วแค่ไหน:
# ตั้งค่า cache pressure (ค่าเริ่มต้นคือ 100 ยิ่งต่ำ = เก็บ cache ไว้นานขึ้น)
sudo sysctl vm.vfs_cache_pressure=50
# ทำให้ถาวร
echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.confนี่คือสคริปต์สำหรับตั้งค่าทั้งหมดในครั้งเดียว (ปรับค่าตามต้องการ):
คอยดูว่า server ใช้ swap มากแค่ไหน:
# ตรวจสอบเร็ว
free -h
# ข้อมูล swap โดยละเอียด
swapon --show
# ดู real-time (อัพเดตทุก 2 วินาที)
watch -n 2 free -h
# ดูว่า process ไหนใช้ swap มากที่สุด
for file in /proc/*/status; do
awk '/VmSwap|Name/ {printf $2 " " $3}' "$file" 2>/dev/null
echo
done | sort -k 2 -n -r | head -10สัญญาณที่บอกว่าต้องเพิ่ม swap:
free -h แสดงว่า swap ใช้เกิน 80% อย่างต่อเนื่องdmesg | grep -i oom แสดง OOM events ล่าสุดวิธีปรับขนาด swap file:
# ปิด swap ปัจจุบัน
sudo swapoff /mnt/volume/swapfile
# ปรับขนาด (เช่น เป็น 8GB)
sudo fallocate -l 8G /mnt/volume/swapfile
# ตั้งค่าใหม่
sudo mkswap /mnt/volume/swapfile
sudo swapon /mnt/volume/swapfile
# ตรวจสอบ
free -hการ build Next.js monorepo ที่มี TypeScript สามารถใช้ RAM 4-6GB ถ้า server มี RAM 8GB โดยไม่มี swap เหลือพื้นที่แทบไม่พอสำหรับ OS และบริการอื่น:
ไม่มี swap:
FATAL ERROR: Ineffective mark-compacts near heap limit
Allocation failed - JavaScript heap out of memory
SIGKILL
มี swap 4GB บน volume:
Build completed successfully in 127s
Peak memory: 5.8GB (4.2GB RAM + 1.6GB swap)
Build จะช้าลงเล็กน้อย (swap ใช้ disk) แต่มัน สำเร็จ แทนที่จะ crash สำหรับ production build server การแลกเปลี่ยนนี้คุ้มค่าเสมอ
กฎง่ายๆ: เท่ากับขนาด RAM แต่ไม่เกิน 8GB เช่น RAM 8GB → swap 4-8GB สำหรับ server ที่ build บ่อย แนะนำขนาดใหญ่กว่า
เฉพาะเมื่อระบบ swap จริงๆ เท่านั้น ด้วย swappiness=10 Linux จะใช้ RAM ก่อนและใช้ swap เป็นตาข่ายนิรภัย คุณจะไม่สังเกตเห็นความแตกต่างในการใช้งานปกติ
ได้ Linux รองรับ swap file หลายไฟล์และยังจัดลำดับความสำคัญได้ แต่สำหรับการใช้งานทั่วไป swap file เดียวบน volume เพียงพอแล้ว
Swap files ปรับขนาดและจัดการง่ายกว่า ความแตกต่างด้านประสิทธิภาพแทบไม่มีบน Linux kernel สมัยใหม่ (4.0+) Swap files เป็นวิธีที่แนะนำ
ตรวจสอบให้แน่ใจว่า volume มีพื้นที่เพียงพอสำหรับทั้ง swap และข้อมูลอื่นที่เก็บไว้ volume 40GB กับ swap file 4GB ยังเหลืออีก 36GB สำหรับข้อมูลอื่น
#!/bin/bash
# ตั้งค่า swap บน Hetzner Cloud volume
# วิธีใช้: sudo bash setup-swap.sh
SWAP_FILE="/mnt/volume/swapfile"
SWAP_SIZE="4G"
SWAPPINESS=10
# สร้าง swap file
echo "กำลังสร้าง ${SWAP_SIZE} swap file ที่ ${SWAP_FILE}..."
fallocate -l ${SWAP_SIZE} ${SWAP_FILE}
chmod 600 ${SWAP_FILE}
mkswap ${SWAP_FILE}
swapon ${SWAP_FILE}
# เพิ่มใน fstab ถ้ายังไม่มี
if ! grep -q "${SWAP_FILE}" /etc/fstab; then
echo "${SWAP_FILE} none swap sw 0 0" >> /etc/fstab
echo "เพิ่มใน /etc/fstab แล้ว"
fi
# ปรับ swappiness
sysctl vm.swappiness=${SWAPPINESS}
if ! grep -q "vm.swappiness" /etc/sysctl.conf; then
echo "vm.swappiness=${SWAPPINESS}" >> /etc/sysctl.conf
fi
# ปรับ cache pressure
sysctl vm.vfs_cache_pressure=50
if ! grep -q "vm.vfs_cache_pressure" /etc/sysctl.conf; then
echo "vm.vfs_cache_pressure=50" >> /etc/sysctl.conf
fi
echo "ตั้งค่า swap เสร็จสมบูรณ์!"
free -h
swapon --show