คำตอบสั้น ๆ: สำรอง Docker Volume เป็นไฟล์ tar.gz สำรองฐานข้อมูลใน Container ด้วย dump กู้คืนกลับ และย้าย Volume ไปเครื่องใหม่ พร้อมสคริปต์สำรองอัตโนมัติ
คู่มือนี้อธิบาย Docker Volume ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
ข้อมูลสำคัญของแอปที่รันบน Docker เช่น ไฟล์อัปโหลดของเว็บไซต์หรือไฟล์ฐานข้อมูล มักเก็บอยู่ใน Docker Volume ซึ่งอยู่รอดแม้ลบ Container แต่ถ้าดิสก์เสีย ลบ Volume ผิดตัว หรือสั่ง docker compose down -v โดยไม่ตั้งใจ ข้อมูลจะหายทั้งหมด การสำรอง Volume ออกมาเป็นไฟล์แล้วเก็บไว้นอกเครื่องจึงจำเป็นเสมอ
บทความนี้แสดงวิธีสำรอง Volume เป็นไฟล์ .tar.gz ด้วย Container ชั่วคราว วิธีกู้คืนกลับ วิธีสำรองฐานข้อมูลใน Container อย่างถูกต้อง และการย้าย Volume ไปเครื่องใหม่
สิ่งที่ต้องเตรียม (Docker Volume)
- Linux Server ที่ใช้ Docker Engine และ Docker Compose Plugin
- สิทธิ์
sudoหรือผู้ใช้ในกลุ่มdocker - พื้นที่ดิสก์ว่างพอสำหรับไฟล์สำรอง ตรวจด้วย
df -h - ที่เก็บไฟล์สำรองนอกเครื่อง เช่น เซิร์ฟเวอร์อีกเครื่อง
ขั้นตอนที่ 1: หาว่าข้อมูลอยู่ใน Volume ใด (Docker Volume)
docker volume ls
DRIVER VOLUME NAME
local wordpress_db_data
local wordpress_wp_data
Volume ที่สร้างจาก Docker Compose จะมีชื่อโปรเจกต์ (ปกติคือชื่อโฟลเดอร์) นำหน้า ตรวจว่า Container ใด Mount Volume ไหนไว้ที่ path ใด
docker inspect -f '{{range .Mounts}}{{.Type}} {{.Name}} {{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' wordpress-wordpress-1
คอลัมน์แรกบอกชนิด volume คือ Named Volume ที่ Docker จัดการ ส่วน bind คือโฟลเดอร์บนเครื่องที่ Mount เข้าไป ถ้าเป็น bind สามารถสำรองโฟลเดอร์นั้นด้วยเครื่องมือปกติ เช่น tar หรือ rsync ได้เลย ขั้นตอนต่อไปนี้ใช้กับชนิด volume
| ข้อมูลใน Volume | วิธีสำรองที่แนะนำ |
|---|---|
| ไฟล์ทั่วไป (เว็บ, อัปโหลด, คอนฟิก) | tar ผ่าน Container ชั่วคราว (ขั้นตอนที่ 2) |
| MySQL / MariaDB | mariadb-dump หรือ mysqldump ผ่าน docker compose exec (ขั้นตอนที่ 3) |
| PostgreSQL | pg_dump ผ่าน docker compose exec |
ขั้นตอนที่ 2: สำรอง Volume เป็นไฟล์ tar (Docker Volume)
หลักการคือรัน Container ชั่วคราวจาก Image debian:bookworm-slim (มี GNU tar) ที่ Mount ทั้ง Volume และโฟลเดอร์สำรองบนเครื่อง แล้วใช้ tar บีบอัดข้อมูลออกมา
เพื่อให้ไฟล์สำรองสมบูรณ์ ควรหยุด Container ที่เขียนข้อมูลลง Volume ก่อน
cd /opt/wordpress
sudo docker compose stop
sudo mkdir -p /backup/docker
sudo docker run --rm \
-v wordpress_wp_data:/data:ro \
-v /backup/docker:/backup \
debian:bookworm-slim tar --numeric-owner -czf /backup/wp_data-$(date +%F).tar.gz -C /data .
--rmลบ Container ชั่วคราวทิ้งเมื่อเสร็จ:roMount Volume แบบอ่านอย่างเดียว ป้องกันการแก้ข้อมูลโดยไม่ตั้งใจ-C /data .ให้ tar เก็บ path แบบสัมพัทธ์ กู้คืนไปที่ Volume อื่นได้สะดวก$(date +%F)ถูกแปลงบนเครื่องก่อนส่งเข้า Container ได้ชื่อไฟล์ เช่นwp_data-2026-09-19.tar.gz
เสร็จแล้วเริ่มระบบกลับ
sudo docker compose start
ตรวจเนื้อหาไฟล์สำรองโดยไม่ต้องแตกไฟล์
tar tzf /backup/docker/wp_data-2026-09-19.tar.gz | head
ควรเห็นรายการไฟล์ เช่น ./wp-config.php และ ./wp-content/
ขั้นตอนที่ 3: สำรองฐานข้อมูลใน Container ด้วย dump
การ tar โฟลเดอร์ข้อมูลของฐานข้อมูลขณะที่ยังทำงานอยู่ อาจได้ไฟล์ที่ไม่สอดคล้องกันและกู้คืนไม่ได้ วิธีที่ปลอดภัยกว่าคือ dump ข้อมูลออกมาเป็น SQL ขณะที่ระบบยังทำงาน ไม่ต้องหยุดเว็บ
MariaDB (Image รุ่น 11 ใช้คำสั่ง mariadb-dump)
cd /opt/wordpress
sudo docker compose exec -T db sh -c \
'exec mariadb-dump --single-transaction --all-databases -uroot -p"$MARIADB_ROOT_PASSWORD"' \
| gzip > /backup/docker/db-$(date +%F).sql.gz
MySQL 8 (Image mysql)
sudo docker compose exec -T db sh -c \
'exec mysqldump --single-transaction --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' \
| gzip > /backup/docker/db-$(date +%F).sql.gz
ใส่ -T ทุกครั้งเมื่อส่งผลลัพธ์ออกไปยังไฟล์ เพื่อไม่ให้ Docker จัดสรร TTY ซึ่งจะแทรกอักขระพิเศษลงในไฟล์ SQL ส่วน sh -c '...' ในเครื่องหมายคำพูดเดี่ยว ทำให้ตัวแปรรหัสผ่านถูกอ่านจาก Environment ภายใน Container ไม่ต้องพิมพ์รหัสผ่านบน Command Line ของเครื่อง
รายละเอียดตัวเลือกของ dump และการกู้คืนบางตาราง ดูที่ สำรองและกู้คืนฐานข้อมูล MySQL/MariaDB ด้วย mysqldump สำหรับ PostgreSQL ดู สำรองและกู้คืน PostgreSQL ด้วย pg_dump และ pg_restore
ขั้นตอนที่ 4: กู้คืน Volume จากไฟล์ tar
หมายเหตุ: การกู้คืนจะเขียนทับข้อมูลใน Volume ปลายทาง ถ้า Volume เดิมยังมีข้อมูลที่อาจต้องใช้ ให้สำรองมันอีกชุดตามขั้นตอนที่ 2 ก่อนเสมอ
หยุด Container ที่ใช้ Volume นั้นก่อน
cd /opt/wordpress
sudo docker compose stop wordpress
ถ้าต้องการกู้คืนให้ Volume สะอาดเหมือนตอนสำรอง ให้ลบไฟล์เดิมใน Volume แล้วแตกไฟล์สำรอง
sudo docker run --rm \
-v wordpress_wp_data:/data \
-v /backup/docker:/backup:ro \
debian:bookworm-slim sh -c 'find /data -mindepth 1 -delete && tar --numeric-owner -xzf /backup/wp_data-2026-09-19.tar.gz -C /data'
ตรวจชื่อ Volume ปลายทางให้ถูกต้องก่อนกด Enter เพราะคำสั่ง find ... -delete ลบข้อมูลทั้งหมดใน Volume นั้นทันที ตัวเลือก --numeric-owner ทั้งตอนสำรองและกู้คืน ทำให้เจ้าของไฟล์ถูกเก็บและคืนเป็นหมายเลข UID/GID เดิม ไม่ถูกแปลงตามชื่อผู้ใช้ใน Container ชั่วคราว จึงไม่ต้องแก้สิทธิ์เพิ่มในกรณีส่วนใหญ่
sudo docker compose start wordpress
กู้คืนฐานข้อมูลจากไฟล์ dump
gunzip -c /backup/docker/db-2026-09-19.sql.gz | \
sudo docker compose exec -T db sh -c 'exec mariadb -uroot -p"$MARIADB_ROOT_PASSWORD"'
สำหรับ Image mysql เปลี่ยน mariadb เป็น mysql และใช้ตัวแปร $MYSQL_ROOT_PASSWORD