Docker keeps images, containers, volumes and build cache in /var/lib/docker, on the system disk by default. On a VPS with a small root disk, or when images and volumes grow, you may want Docker’s data on a separate, larger disk. This is done with the data-root setting. It’s a straightforward move if you follow the steps.
First: do you really need to move it?
Often the disk is full of unused data:
docker system df
docker system prune -a # removes stopped containers, unused images, networks, build cache
docker builder prune -a
docker system prune does not remove volumes unless you add --volumes. Check before using that. See Docker disk cleanup. Also check container logs, which can be huge. See Docker logging drivers.
If you still need more space, move the data, or add storage.
Prepare the new disk
Mount it permanently (for example at /data), using its UUID in /etc/fstab. See fstab guide and mount options.
lsblk -f
df -h /data
Use a Linux filesystem (ext4 or XFS). Docker’s overlay2 storage driver needs one: no NFS, CIFS or FUSE mounts. See ext4 vs XFS.
Move the data
# 1. stop Docker (and the socket, so it doesn't restart)
sudo systemctl stop docker docker.socket containerd
# 2. copy, preserving everything
sudo mkdir -p /data/docker
sudo rsync -aHAX --numeric-ids --info=progress2 /var/lib/docker/ /data/docker/
# 3. point Docker at the new location
sudo nano /etc/docker/daemon.json
{
"data-root": "/data/docker"
}
(Merge it with any existing settings in the file, such as log options.)
# 4. keep the old directory as a backup for now
sudo mv /var/lib/docker /var/lib/docker.old
# 5. start Docker
sudo systemctl start docker
docker info --format '{{.DockerRootDir}}' # should show /data/docker
docker ps -a
docker images
Start your stacks (docker compose up -d), and test them. Once everything works, delete the old copy:
sudo rm -rf /var/lib/docker.old
Roll back
If something’s wrong: stop Docker, remove data-root from daemon.json, move /var/lib/docker.old back to /var/lib/docker, and start Docker again.
containerd’s data
With the classic storage setup, image layers live under Docker’s data root. If your Docker uses the containerd image store (an option in newer versions), image content lives in /var/lib/containerd. Move that too, by setting root in /etc/containerd/config.toml, or symlink/bind-mount it. Check docker info for “Storage Driver” and the containerd snapshotter.
Alternative: bind mount instead of data-root
Some admins keep the default path, and bind-mount the new disk there:
/data/docker /var/lib/docker none bind 0 0
That works too, and keeps tools that assume /var/lib/docker happy. Pick one method, not both.
Volumes vs data-root
Named volumes live under <data-root>/volumes/, so they move with Docker. Bind mounts (./data:/data in Compose) stay wherever their host path is. Move those separately if needed. See Docker volumes and Docker volume backups.
Quick reference
| Step | Command |
|---|---|
| Check usage | docker system df |
| Stop Docker | systemctl stop docker docker.socket containerd |
| Copy | rsync -aHAX --numeric-ids /var/lib/docker/ /data/docker/ |
| Configure | "data-root": "/data/docker" in daemon.json |
| Verify | docker info --format '{{.DockerRootDir}}' |
Related: VPS storage planning and storage VPS.