เหตุผลที่ต้องย้าย
VPS / server เกือบทั้งหมดมี layout แบบนี้:
/ — 20-30 GB (root partition)
/data — 200 GB (data disk แยก)
Docker default เก็บข้อมูลที่ /var/lib/docker = อยู่ใน root partition
ถ้ามี container เยอะ image เยอะ — root เต็มเร็วมาก ทั้งที่ /data ยังว่าง
ทางเลือก:
- A: ตั้ง
data-rootใน daemon config (วิธีถูกต้อง) - B: ย้าย folder + symlink (วิธีเก่า แต่ใช้ได้)
ทั้งสองวิธีโอเค ขอแนะนำ A แต่ถ้า script เก่า/tool บางตัว hardcode path /var/lib/docker — B ปลอดภัยกว่า
วิธี A: data-root config (แนะนำ)
Step 1: หยุด docker
sudo systemctl stop docker docker.socket
Step 2: ย้ายข้อมูล
sudo mkdir -p /data/docker
sudo rsync -aHAX --info=progress2 /var/lib/docker/ /data/docker/
flags ที่ใช้:
-aarchive (preserve permissions, owner, time)-Hhardlinks-AACLs-Xextended attributes (สำคัญสำหรับ overlay2)
หรือใช้ cp -a ถ้าไม่มี rsync — แต่ rsync ทน interrupt ได้ดีกว่า
ตรวจสอบขนาด:
sudo du -sh /var/lib/docker /data/docker
# ขนาดควรเท่ากัน
Step 3: ตั้ง daemon config
/etc/docker/daemon.json:
{
"data-root": "/data/docker"
}
ถ้ามี config อยู่แล้ว — merge กัน:
{
"data-root": "/data/docker",
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
Step 4: rename folder เก่า + start
sudo mv /var/lib/docker /var/lib/docker.bak
sudo systemctl start docker
Step 5: verify
docker info | grep -i "docker root"
# Docker Root Dir: /data/docker
docker ps -a # container เก่ายังอยู่
docker images # image เก่ายังอยู่
ถ้าทำงานปกติ — ลบ folder เก่า:
sudo rm -rf /var/lib/docker.bak
วิธี B: Symlink
ใช้เมื่อ tool/script เก่าใน server hardcode path /var/lib/docker (rare แต่เคยเจอ)
Step 1-2: เหมือน A (หยุด docker, ย้ายข้อมูล)
Step 3: ทำ symlink แทน data-root config
sudo mv /var/lib/docker /var/lib/docker.bak
sudo ln -s /data/docker /var/lib/docker
# verify
ls -la /var/lib/docker
# lrwxrwxrwx ... /var/lib/docker -> /data/docker
Step 4: start docker
sudo systemctl start docker
docker ps -a
กับดักของ symlink
1. Mount option ของ /data ต้อง support overlay
sudo mount | grep /data
# ควรไม่เห็น "nodev" หรือ "nosuid" ถ้าเห็น overlay จะพัง
แก้ /etc/fstab:
/dev/sdb1 /data ext4 defaults 0 2
2. SELinux อาจ block
CentOS / RHEL / Rocky:
sudo semanage fcontext -a -e /var/lib/docker /data/docker
sudo restorecon -R /data/docker
3. Ubuntu AppArmor
ตรวจ:
sudo aa-status | grep docker
ถ้ามี profile docker — อาจต้อง edit profile ให้ยอม path ใหม่ หรือใช้วิธี A แทน
วิธี C: bind mount
อีกวิธีที่ clean — bind mount แทน symlink:
/etc/fstab:
/data/docker /var/lib/docker none bind 0 0
sudo mkdir -p /var/lib/docker
sudo mount -a
mount | grep docker
# /data/docker on /var/lib/docker type none (rw,bind)
ดี: ไม่มี symlink — tool เก่าเห็น /var/lib/docker ปกติ
เสีย: ต้องตั้ง fstab + reboot test ว่ายัง mount หลัง restart
ทดสอบหลังย้าย
# 1. docker info
docker info | grep "Docker Root Dir"
# 2. รัน hello-world
docker run --rm hello-world
# 3. ตรวจ disk
df -h /data /var/lib/docker
# 4. start container เดิมที่เคยรันอยู่
docker compose up -d # ในแต่ละ project folder
ข้อผิดพลาดที่ต้องระวัง
1. ลืมหยุด docker ก่อน rsync → ข้อมูลไม่ครบ container เก่าอ่านไม่ได้
2. rsync ขาด -X flag → overlay metadata หาย — image พังต้อง pull ใหม่
3. ลบ folder เก่าเร็วเกิน → ถ้ามีปัญหา rollback ไม่ได้ เก็บไว้อย่างน้อย 1 อาทิตย์
4. /data partition ไม่มี exec permission → container start ไม่ได้
sudo mount -o remount,exec /data
ป้องกันตั้งแต่ install ครั้งแรก
ถ้ารู้ว่า server มี data partition แยก — ตั้ง data-root ตั้งแต่แรกก่อน install service ใดๆ
# ตอน setup server
sudo mkdir -p /data/docker
echo '{"data-root": "/data/docker"}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
เช็ค space ใช้จริง
หลังย้าย ดูว่า /var ว่างขึ้นจริงมั้ย:
sudo du -sh /var/lib /data/docker
df -h
ถ้ายังเต็ม — มีของอื่น เช่น log, snap, journal:
sudo du -sh /var/log /var/lib/snapd /var/cache /var/tmp
sudo journalctl --vacuum-size=500M
sudo apt clean
TLDR
# วิธีที่ง่ายและ safe ที่สุด
sudo systemctl stop docker docker.socket
sudo mkdir -p /data/docker
sudo rsync -aHAX /var/lib/docker/ /data/docker/
echo '{"data-root": "/data/docker"}' | sudo tee /etc/docker/daemon.json
sudo mv /var/lib/docker /var/lib/docker.bak
sudo systemctl start docker
# ตรวจ
docker info | grep "Docker Root Dir"
docker ps -a
# หลังใช้ปกติ 1 อาทิตย์
sudo rm -rf /var/lib/docker.bak
สรุป
ย้าย Docker directory เป็นการ maintenance พื้นฐานที่ทำครั้งเดียวอยู่ได้นาน
data-root config = วิธีที่ Docker design มาให้ทำตั้งแต่แรก ใช้เลย
Symlink = backup plan สำหรับ edge case
อย่าลืมเช็ค --info=progress2 ตอน rsync ขนาดใหญ่ — ดู progress real-time จะรู้ว่าจะเสร็จเมื่อไหร่