Docker & DevOps

Move Docker data root to another disk or path

Move Docker's data from /var/lib/docker to a bigger disk. Stop the daemon, copy the data, set data-root in daemon.json, handle the containerd image store and verify images and volumes survived.

IntermediateLinux server5 min read

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 overlay2 storage driver needs XFS to be created with ftype=1, which is the default on current systems.
  • Free space on the new disk larger than what Docker uses now:
Bash
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:

Bash
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:

Bash
sudo systemctl stop docker.service docker.socket
sudo systemctl status docker --no-pager

The status should show inactive (dead).

Copy the data

Use rsync with flags that keep permissions, ownership, hard links, ACLs and extended attributes:

Bash
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:

Bash
sudo mv /var/lib/docker /var/lib/docker.old

Set data-root in daemon.json

Edit the daemon configuration:

Bash
sudo nano /etc/docker/daemon.json

If the file is new, add:

JSON
{
  "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:

Bash
sudo dockerd --validate --config-file /etc/docker/daemon.json

It 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

Bash
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:

Bash
docker image ls
docker volume ls
docker ps -a

The same images, volumes and containers should be listed as before. Start your stacks and check each app works and still has its data:

Bash
cd /opt/stacks/myapp && docker compose up -d

Finally, confirm new data is written to the new disk:

Bash
df -h /mnt/data

Clean 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.

Bash
sudo rm -rf /var/lib/docker.old

Troubleshooting

  • 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. Check docker info and 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

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.