Docker keeps images, containers and volumes under /var/lib/docker on the root filesystem. When you add a second disk or the root partition is small, you can move that data and point Docker at the new location. This guide does it safely: stop Docker, copy rather than move, switch the setting, verify, and only then delete the old copy.
Before you start
- A Linux VPS with Docker Engine installed and root or sudo access.
- The new disk mounted permanently, for example at
/mnt/data, with an entry in/etc/fstab. See Add a new disk to a Linux VPS. - An ext4 or XFS filesystem on the new disk. The
overlay2storage driver needs XFS to be created withftype=1, which is the default on current systems. - Free space on the new disk larger than what Docker uses now:
sudo du -sh /var/lib/docker /var/lib/containerd 2>/dev/null- A backup of important volumes and databases.
Warning: All containers stop while you do this. Plan for downtime of a few minutes plus the time to copy the data.
Check which image store Docker uses
Docker Engine 29 and later use the containerd image store by default on new installations. With it, image layers and container snapshots live under /var/lib/containerd, and the data-root setting does not move them. Older installs, and installs upgraded from older versions, use the classic overlay2 driver with everything under /var/lib/docker.
Find out which one you have:
docker info --format '{{.Driver}}'
docker info | grep -i -E 'storage driver|driver-type|docker root dir'If the storage driver is overlay2 and there is no mention of io.containerd.snapshotter, the classic layout applies and moving data-root moves everything. If it shows a containerd snapshotter, read the section on containerd below as well.
Stop Docker
Stop the service and its socket, so a command cannot start it again halfway through:
sudo systemctl stop docker.service docker.socket
sudo systemctl status docker --no-pagerThe status should show inactive (dead).
Copy the data
Use rsync with flags that keep permissions, ownership, hard links, ACLs and extended attributes:
sudo mkdir -p /mnt/data/docker
sudo rsync -aHAX --info=progress2 /var/lib/docker/ /mnt/data/docker/The trailing slashes matter: they copy the contents of the folder into the new folder. Then rename the old folder, so Docker cannot use it by accident and you still have a way back:
sudo mv /var/lib/docker /var/lib/docker.oldSet data-root in daemon.json
Edit the daemon configuration:
sudo nano /etc/docker/daemon.jsonIf the file is new, add:
{
"data-root": "/mnt/data/docker"
}If it already has settings, add the data-root line inside the existing braces and keep a comma between entries. Validate the file before starting:
sudo dockerd --validate --config-file /etc/docker/daemon.jsonIt should print configuration OK.
Move containerd data too, if needed
If Docker uses the containerd image store, image data is managed by containerd. To move it, stop containerd as well, copy /var/lib/containerd to the new disk, and set the root option in /etc/containerd/config.toml to the new path. The exact file contents depend on your containerd version, so follow the current Docker and containerd documentation for this step.
A simpler alternative for a small VPS is to leave containerd in place and only move volumes, or to mount the new disk directly at /var/lib/containerd. Test either approach on a non-production server first.
Start Docker and verify
sudo systemctl start docker
docker info | grep 'Docker Root Dir'The output should read Docker Root Dir: /mnt/data/docker.
Check it works
Confirm the data came across:
docker image ls
docker volume ls
docker ps -aThe same images, volumes and containers should be listed as before. Start your stacks and check each app works and still has its data:
cd /opt/stacks/myapp && docker compose up -dFinally, confirm new data is written to the new disk:
df -h /mnt/dataClean up the old copy
Keep /var/lib/docker.old for a few days. When you are sure everything works, remove it:
Warning: This deletes the old Docker data permanently. Only do it after you have verified every app on the new location.
sudo rm -rf /var/lib/docker.oldTroubleshooting
- Docker will not start after the change: read
sudo journalctl -u docker -n 50. A JSON syntax error or a wrong path is the usual cause. See Fix Docker daemon not starting. - Images are missing after the move: Docker uses the containerd image store, so images live in
/var/lib/containerd, or the rsync source path was wrong. Checkdocker infoand the copy. - Containers start but volumes look empty: the copy did not include
volumes/. Stop Docker, rerun the rsync from/var/lib/docker.old/, then start again. - The disk is missing after a reboot and Docker creates an empty folder: the mount is not in
/etc/fstab. Fix the mount, then restart Docker.
To roll back, stop Docker, remove the data-root line, rename /var/lib/docker.old back to /var/lib/docker and start Docker.
Next steps
- Reclaim space before moving: Free disk space with docker system prune.
- Diagnose disk growth: Fix Docker filling the disk (overlay2).
