Volume: dữ liệu container thực sự nằm ở đâu
Volume có tên khác gì so với bind mount, tất cả thực sự nằm ở đâu trên ổ đĩa, và cách không làm mất cơ sở dữ liệu khi tạo lại container.
Cập nhật 23 tháng 8, 2026
Container là thứ dùng một lần. Mọi thứ ghi bên trong nó sẽ biến mất cùng nó. Dữ liệu phải nằm bên ngoài, và chỉ có đúng hai cách: volume có tên và bind mount thư mục trên máy chủ.
Hai cách và khi nào dùng mỗi cách
services:
db:
image: postgres:17
volumes:
- db-data:/var/lib/postgresql/data # named volume
app:
image: nginx:1.27
volumes:
- ./site:/usr/share/nginx/html:ro # directory bind mount
- ./nginx.conf:/etc/nginx/nginx.conf:ro
volumes:
db-data:
Volume có tên do chính Docker tạo và lưu trữ, trong /var/lib/docker/volumes/<name>/_data. Quyền bên trong được image thiết lập tự động. Đây là cách lưu giữ cơ sở dữ liệu và trạng thái nội bộ của dịch vụ.
Bind mount thư mục là một đường dẫn thông thường trên đĩa của máy. Đây là cách bạn cung cấp tệp cấu hình, tài nguyên tĩnh của website và chứng chỉ: chúng thuận tiện để chỉnh sửa bằng trình soạn thảo và lưu trong kho mã nguồn.
Cờ :ro khiến mount chỉ đọc. Hãy dùng nó ở mọi nơi mà container không cần quyền ghi — đây là lớp bảo vệ rẻ mà hiệu quả.
Mọi thứ thực sự được lưu ở đâu
docker volume ls
docker volume inspect db-data
docker inspect -f '{{json .Mounts}}' <container> | python3 -m json.tool
sudo du -sh /var/lib/docker/volumes/* | sort -h | tail
Lệnh cuối cùng là thứ đầu tiên cần chạy khi hết dung lượng đĩa. Chi tiết: dung lượng đĩa.
docker compose down -vvàdocker volume prunexóa volume vĩnh viễn. Một volume chứa cơ sở dữ liệu trông như “không dùng” khi container đã dừng và sẽ nằm trong diện bị dọn. Trước khi dọn, hãy xem danh sách:docker volume ls -f dangling=true.
Sao chép và di chuyển
Sao chép một volume có tên bằng container dùng một lần:
docker run --rm -v db-data:/from -v $(pwd):/to alpine \
tar czf /to/db-data.tar.gz -C /from .
Khôi phục:
docker volume create db-data
docker run --rm -v db-data:/to -v $(pwd):/from alpine \
tar xzf /from/db-data.tar.gz -C /to
Với cơ sở dữ liệu, cách này chỉ phù hợp khi container đã dừng: sao chép ở mức tệp của một cơ sở dữ liệu đang chạy có thể không nhất quán. Tốt hơn là dump bằng công cụ riêng của cơ sở dữ liệu — pg_dump, mysqldump. Xem cần sao chép chính xác những gì.
Quyền
Lỗi phổ biến nhất với bind mount là chủ sở hữu không khớp. Bên trong container, tiến trình chạy dưới UID riêng của nó, và một tệp do máy chủ tạo với quyền root sẽ không truy cập được từ đó.
docker compose exec app id
sudo chown -R 1000:1000 ./data
Nhiều image chấp nhận các biến PUID/PGID — cách này thuận tiện hơn việc đổi chủ sở hữu thư mục.
Những lỗi thường gặp
- Dữ liệu được ghi bên trong container. Bạn tạo lại container trong lúc cập nhật — dữ liệu biến mất. Kiểm tra:
docker diff <container>sẽ cho thấy những gì đã thay đổi trong hệ thống tệp của nó; ghi nhiều dữ liệu ở đó là dấu hiệu cảnh báo. - Bạn bind mount một thư mục đè lên đường dẫn không rỗng trong image. Nội dung của image bị che khuất, và dịch vụ không tìm thấy tệp của nó.
- Đường dẫn tương đối trong bind mount. Nó được phân giải từ thư mục chứa
compose.yaml, không phải từ thư mục hiện tại. Chạy từ vị trí khác sẽ tạo một thư mục rỗng mới. - Quên volume khi cài lại hệ điều hành. Cài lại sẽ xóa sạch toàn bộ đĩa. Bản sao phải được lưu không phải trên máy này.