ย้าย Docker Container ข้าม Server โดยไม่ Downtime

ความท้าทายของการย้าย Docker

การย้าย Docker Container ข้าม Server โดยไม่ให้ระบบล่มได้นั้น ต้องวางแผนให้ดีก่อน งานนี้ครอบคลุม 3 ส่วนหลัก: ย้าย Image, ย้าย Volume และสลับ Traffic

ขั้นตอนโดยรวม

1. เตรียม Server ใหม่ (install Docker)
2. ส่ง Image ไป Server ใหม่
3. Backup และย้าย Volume
4. ตั้งค่าและ Start Container บน Server ใหม่
5. ทดสอบให้แน่ใจ
6. สลับ Traffic (DNS/Proxy)
7. ยืนยันและ Cleanup

วิธีที่ 1: ส่ง Image ผ่าน Registry

# Server เดิม: push Image ไป Registry
docker tag myapp:latest registry.yourdomain.com/myapp:latest
docker push registry.yourdomain.com/myapp:latest

# Server ใหม่: pull Image
docker pull registry.yourdomain.com/myapp:latest

วิธีที่ 2: ส่ง Image โดยตรง (ไม่มี Registry)

# Export Image
docker save myapp:latest | gzip > myapp.tar.gz

# Copy ไป Server ใหม่
scp myapp.tar.gz user@new-server:/tmp/

# Import บน Server ใหม่
docker load < /tmp/myapp.tar.gz

ย้าย Docker Volume

# Server เดิม: Backup Volume
docker run --rm \
  -v myapp_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/volume_backup.tar.gz /data

# Copy ไป Server ใหม่
scp volume_backup.tar.gz user@new-server:/tmp/

# Server ใหม่: Restore Volume
docker volume create myapp_data
docker run --rm \
  -v myapp_data:/data \
  -v /tmp:/backup \
  alpine tar xzf /backup/volume_backup.tar.gz -C /

ย้าย MySQL Database

# Server เดิม: Dump database
docker exec mysql_server \
  mysqldump -u root -prootpassword --all-databases \
  > all_databases.sql

# Copy
scp all_databases.sql user@new-server:/tmp/

# Server ใหม่: Restore
docker exec -i mysql_server \
  mysql -u root -prootpassword < /tmp/all_databases.sql

Zero Downtime ด้วย Blue-Green Deployment

# 1. Start Container บน Server ใหม่
docker compose up -d

# 2. ทดสอบให้แน่ใจ
curl https://new-server-ip/health

# 3. เปลี่ยน DNS ชี้ A record ยัง IP ใหม่
# (propagate สักหน่อยตาม TTL)

# 4. Nginx Upstream Swap (ถ้าใช้ Nginx เป็น Load Balancer)
upstream backend {
  server new-server-ip:80;   # สลับจาก old เป็น new
  # server old-server-ip:80; # comment out
}

# 5. nginx reload
nginx -s reload  # Zero downtime!

Script ย้ายแบบอัตโนมัติ

#!/bin/bash
NEW_SERVER="user@new-server-ip"

# 1. Export Images
echo "Saving Docker images..."
docker save $(docker images -q) | gzip > all_images.tar.gz

# 2. Backup Volumes
echo "Backing up volumes..."
for vol in $(docker volume ls -q); do
  docker run --rm -v ${vol}:/data -v $(pwd):/backup \
    alpine tar czf /backup/${vol}.tar.gz /data
done

# 3. Copyไป Server ใหม่
echo "Transferring to new server..."
scp all_images.tar.gz ${NEW_SERVER}:/tmp/
scp *.tar.gz ${NEW_SERVER}:/tmp/
scp docker-compose.yml .env ${NEW_SERVER}:/opt/myapp/

echo "Done! Now restore on new server."

สรุป

การย้าย Docker Container โดยไม่มี Downtime ต้องอาศัย Blue-Green Deployment หรือการสลับ Traffic ผ่าน Load Balancer Docker ทำให้กระบวนการนี้ง่ายกว่าเดิมมากเพราะ Image และ Volume เคลื่อนย้ายได้ง่าย