Làm sao để dịch chuyển container có volume sang một host khác? Migrate container with volume to other hosts?
Mở đầu
Trong môi trường vận hành ứng dụng bằng Docker, việc cần di chuyển container sang host mới là chuyện khá phổ biến — có thể vì nâng cấp hạ tầng, thay đổi môi trường, hoặc tối ưu tài nguyên.
Tuy nhiên, nếu container sử dụng Docker volume để lưu dữ liệu (ví dụ cơ sở dữ liệu MySQL, PostgreSQL, file upload, logs, …), việc migrate không thể chỉ đơn giản là “docker save + docker load” vì dữ liệu thật nằm ở volume trên host, chứ không nằm trong image.
Bài viết này hướng dẫn chi tiết hai cách phổ biến để migrate container có volume sang host mới mà vẫn giữ nguyên dữ liệu:
- Dùng file nén .tar để sao lưu và khôi phục dữ liệu.
- Dùng rsync để đồng bộ dữ liệu giữa hai host, phù hợp với trường hợp cần downtime ngắn hoặc liên tục cập nhật dữ liệu.
Docker quản lý và lưu trữ dữ liệu volume trong host thế nào?
Khi bạn tạo một volume, Docker sẽ lưu dữ liệu trong thư mục hệ thống của host — mặc định là:
/var/lib/docker/volumes/<volume_name>/_data
Ví dụ, với docker-compose.yml sau:
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Docker sẽ tạo một volume tên là db_data, và toàn bộ dữ liệu MySQL thật sự nằm trong folder:
/var/lib/docker/volumes/db_data/_data
Một vài đặc điểm của volume trong Docker:
- Volume được Docker quản lý độc lập với container.
- Khi container bị xoá
(docker rm), dữ liệu trong volume vẫn còn. - Volume chỉ bị mất khi bạn thực sự chạy
docker volume rm <volume_name>.
Vì vậy, nếu muốn di chuyển dữ liệu, bạn chỉ cần di chuyển toàn bộ thư mục _data của volume sang host mới và gắn lại cho container tương ứng.
Giải pháp 1: Nén dữ liệu trong volume thành file .tar và khôi phục
Đọc qua tên giải pháp này chắc bạn cũng hình dung được cách chúng ta sẽ thực hiện. Chúng ta sẽ nén dữ liệu của volume ở Host hiện tại thành 1 file nén rồi copy qua bên host mới. Dưới đây là các bước để bạn có thể thực hiện theo cách này.
- Trên host cũ, Xác định tên volume cần sao lưu bằng command sau:
docker volume ls
- Ví dụ ta thấy volume db_data. Tạo file backup .tar.gz:
docker run --rm \
-v db_data:/volume_data \
-v $(pwd):/backup \
alpine sh -c "cd /volume_data && tar czf /backup/db_data_backup.tar.gz ."
- -v db_data:/volume_data: mount volume cần backup vào container tạm.
- -v $(pwd):/backup: mount thư mục hiện tại để lưu file nén.
- File nén sẽ được tạo tại $(pwd)/db_data_backup.tar.gz.
- Chuyển file nén sang host mới:
scp db_data_backup.tar.gz user@new-host:/home/user/backup/
- Trên host mới, Tạo volume trống có cùng tên:
docker volume create db_data
- Giải nén dữ liệu vào volume mới:
docker run --rm \
-v db_data:/volume_data \
-v $(pwd):/backup \
alpine sh -c "cd /volume_data && tar xzf /backup/db_data_backup.tar.gz"
- Khởi động lại container trên host mới:
docker compose up -d
- Kiểm tra dữ liệu:
docker exec -it <container_name> ls /var/lib/mysql
Ưu điểm
- Đơn giản, dễ thực hiện.
- Không cần cấu hình mạng giữa hai host.
- Phù hợp với môi trường nhỏ, cần backup/lưu trữ định kỳ.
Nhược điểm
- Phải dừng container trong lúc backup để tránh ghi dữ liệu mới.
- Quá trình nén/giải nén mất thời gian nếu dữ liệu lớn.
- Không thích hợp cho môi trường yêu cầu downtime thấp.
Giải pháp 2: Dùng rsync để đồng bộ dữ liệu giữa hai host
Phương pháp này đồng bộ dữ liệu 2 folder , phù hợp với trường hợp muốn chuyển dần đối với lượng dữ liệu lớn, giảm downtime, hoặc dữ liệu thay đổi liên tục. Cách thực hiện như sau:
Bước 1. Xác định thư mục dữ liệu volume:
docker volume inspect db_data | grep Mountpoint
Kết quả ví dụ:
"Mountpoint": "/var/lib/docker/volumes/db_data/_data"
Bước 2. Dùng rsync để đồng bộ dữ liệu:
Trên host mới chạy:
rsync -avz -e ssh user@old-host:/var/lib/docker/volumes/db_data/_data/ \
/var/lib/docker/volumes/db_data/_data/
Hoặc nếu muốn thực hiện từ host cũ:
rsync -avz /var/lib/docker/volumes/db_data/_data/ \
user@new-host:/var/lib/docker/volumes/db_data/_data/
- -a: đồng bộ toàn bộ quyền, file, thư mục.
- -v: hiển thị chi tiết tiến trình.
- -z: nén dữ liệu khi truyền để tiết kiệm băng thông.
- -e ssh: truyền qua SSH an toàn.
Bước 3. Kiểm tra dữ liệu sau đồng bộ:
ssh user@new-host "ls -lh /var/lib/docker/volumes/db_data/_data/"
Bước 4. Hạn chế downtime bằng rsync incremental
Lần đầu có thể đồng bộ toàn bộ dữ liệu (mất thời gian), nhưng sau đó có thể chạy lại rsync nhiều lần để đồng bộ phần thay đổi nhỏ.
Ví dụ:
# Lần đầu đồng bộ (khi hệ thống vẫn đang hoạt động)
rsync -avz user@old-host:/var/lib/docker/volumes/db_data/_data/ /tmp/db_sync/
# Sau khi chuẩn bị sẵn host mới, dừng container trên host cũ
docker compose down
# Chạy rsync lần cuối để cập nhật dữ liệu mới nhất
rsync -avz --delete user@old-host:/var/lib/docker/volumes/db_data/_data/ \
/var/lib/docker/volumes/db_data/_data/
# Khởi động container trên host mới
docker compose up -d
Ưu điểm
- Có thể giảm downtime gần như bằng 0 nhờ đồng bộ liên tục.
- Phù hợp với dữ liệu lớn hoặc hệ thống đang hoạt động.
- Có thể chạy nhiều lần để đảm bảo dữ liệu mới nhất.
Nhược điểm
- Cần kết nối mạng SSH giữa hai host.
- Phải đảm bảo version và permission tương thích.
- Nếu volume đang được ghi liên tục, có thể cần downtime ngắn để rsync lần cuối.
Lưu ý thêm
- Luôn kiểm tra đường dẫn mount point: Sử dụng docker volume inspect <volume_name> để chắc chắn bạn di chuyển đúng dữ liệu.
- Cẩn trọng với permission và user: Nếu container chạy với user cụ thể (ví dụ mysql UID khác root), hãy đảm bảo dữ liệu giữ nguyên quyền truy cập. Có thể cần chown lại sau khi restore.
- Kiểm tra project name khi dùng Docker Compose: Volume có thể được đặt tên với prefix (ví dụ myapp_db_data), cần đảm bảo tên khớp với docker-compose.yml trên host mới.
- Downtime và consistency: Dừng container trước khi backup hoặc thực hiện rsync lần cuối để tránh mất dữ liệu.
- Phiên bản Docker / image: Đảm bảo hai host dùng cùng phiên bản Docker và cùng image tag (ví dụ mysql:8.0) để tránh lỗi không tương thích dữ liệu.
Kết
Việc migrate container có volume sang host mới không chỉ là sao chép image — mà quan trọng nhất là đảm bảo dữ liệu trong volume được di chuyển an toàn và nhất quán.
- Nếu bạn muốn đơn giản, backup một lần, không cần mạng giữa hai host → dùng giải pháp .tar.
- Nếu bạn cần đồng bộ liên tục, giảm downtime, dữ liệu lớn → chọn giải pháp rsync.
Tùy vào nhu cầu và quy mô hệ thống, bạn có thể kết hợp cả hai: dùng rsync để đồng bộ trước, rồi .tar để lưu trữ lâu dài.
Việc hiểu rõ cách Docker quản lý dữ liệu sẽ giúp bạn thực hiện migration tự tin và tránh mất dữ liệu ngoài ý muốn.
Nếu bài viết có ích cho bạn hãy Follow và Upvote bài viết để ủng hộ mình nhé. Cám ơn bạn ❤️
Nếu như bạn đang gặp khó khăn trong vấn đề chuyên môn, cần người hỗ trợ về mặt hệ thống, DevOps tools hay cần định hướng trong công việc thì mình tự tin có thể hỗ trợ được bạn. Liên hệ với mình để trao đổi thêm nhé https://hoangviet.io.vn/, mình rất vui khi được trao đổi và cộng tác với bạn.
All Rights Reserved