Docker’s default storage location (/var/lib/docker) can fill up quickly, especially on systems with limited space like a Raspberry Pi’s SD card. This guide walks you through installing Docker on Debian and moving its storage to an external disk for better performance and management. Let’s dive in!

Step 1: Install Docker

Follow this official setup to install docker in Debian: https://docs.docker.com/engine/install/debian/

Step 2: Verify Docker’s current storage location

Before making changes, it’s essential to check where Docker currently stores its volumes. Run this command to see where Docker stores its data:
docker info | grep "Docker Root Dir"
You’ll likely see:
Docker Root Dir: /var/lib/docker
This confirms the default storage location (we’ll change later).

Step 3: Check Disk Usage

Before adding containers, check your disk space:

df -h
root@vbox:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            953M     0  953M   0% /dev
tmpfs           197M  1.3M  196M   1% /run
/dev/sda1        19G  5.7G   12G  33% /
tmpfs           984M     0  984M   0% /dev/shm
tmpfs           5.0M  8.0K  5.0M   1% /run/lock
tmpfs           197M   84K  197M   1% /run/user/1000

Step 4: Start some Containers

Add a few containers to simulate usage:

docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
docker run --name some-nginx -p 8080:80 -v /some/content:/usr/share/nginx/html:ro -d nginx
docker run --name some-drupal -p 8081:80 -d drupal

Step 5: Check the current disk usage

df -h
root@vbox:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            953M     0  953M   0% /dev
tmpfs           197M  1.5M  196M   1% /run
/dev/sda1        19G  9.0G  8.8G  51% /
tmpfs           984M     0  984M   0% /dev/shm
tmpfs           5.0M  8.0K  5.0M   1% /run/lock
tmpfs           197M   84K  197M   1% /run/user/1000
overlay          19G  9.0G  8.8G  51% /var/lib/docker/overlay2/5ce0660852449f15e51c7976a8d7a095ff828d7cbde18899f41057b3fa84a7eb/merged
overlay          19G  9.0G  8.8G  51% /var/lib/docker/overlay2/8a8b573a91b37136ad195d8e77f49aa899646de13cc018642ff37a0fd682fa5a/merged
overlay          19G  9.0G  8.8G  51% /var/lib/docker/overlay2/a86a940a3c481f91605aa2b76f6352b0c327658eee7e47242a7ca7991119038b/merged

It’s clear that Docker has created overlay filesystems for each container, all tied to the /dev/sda1 partition (root filesystem). These overlays inherit the size, used space, and available space from /dev/sda1.

Step 6: Add new disk on VirtualBox

In VirtualBox, attach a new disk to your VM (see screenshot below), then reboot.

virtualbox newdisk

Step 7: Format and Mount the New Disk

Run the following command to list available disks and partitions:

fdisk -lu

available disks

Run the following command to query the UUIDs, partition names, and file system types of the data disks:

blkid
root@vbox:~# blkid
/dev/sda5: UUID="11019ddf-0c5c-43a8-8b12-f2b34510ccac" TYPE="swap" PARTUUID="7504e6d7-05"
/dev/sda1: UUID="a183cb32-35c7-43f6-ace7-52192ea89f36" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="7504e6d7-01"

Since the /dev/sdb has no filesystem or metadata, blkid will not display it. So, run the following command to format the /dev/sdb disk with the ext4 filesystem:

mkfs.ext4 /dev/sdb

Running again blkid.
/dev/sdb should appear with a UUID and type ext4:

root@vbox:~# blkid
/dev/sda5: UUID="11019ddf-0c5c-43a8-8b12-f2b34510ccac" TYPE="swap" PARTUUID="7504e6d7-05"
/dev/sda1: UUID="a183cb32-35c7-43f6-ace7-52192ea89f36" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="7504e6d7-01"
/dev/sdb: UUID="8a3b77ef-c891-4a07-86e9-066c83c951de" BLOCK_SIZE="4096" TYPE="ext4"

To create the /disk2 mount point and mount the /dev/sdb partition, use the following commands:

mkdir /disk2
mount /dev/sdb /disk2

This will make the contents of /dev/sdb accessible under /disk2 directory.

Run the following command to check whether file systems are mounted on the data disk partitions:

root@vbox:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            953M     0  953M   0% /dev
tmpfs           197M  1.2M  196M   1% /run
/dev/sda1        19G  9.0G  8.8G  51% /
tmpfs           984M     0  984M   0% /dev/shm
tmpfs           5.0M  8.0K  5.0M   1% /run/lock
tmpfs           197M   60K  197M   1% /run/user/112
tmpfs           197M   52K  197M   1% /run/user/1000
/dev/sdb         15G   24K   14G   1% /disk2

As shown in the output, the disk /dev/sdb, which was created earlier in this step, is now successfully mounted at /disk2, making it accessible for storage and usage.

To ensure the disk remains mounted after a reboot, add an entry to /etc/fstab:

vi /etc/fstab

Add the following mount information based on the output of the last blkid command:

UUID="8a3b77ef-c891-4a07-86e9-066c83c951de" /disk2      ext4    defaults          0 0

Final result:

UUID=a183cb32-35c7-43f6-ace7-52192ea89f36   /           ext4    errors=remount-ro 0 1
UUID=11019ddf-0c5c-43a8-8b12-f2b34510ccac   none        swap    sw                0 0
UUID="8a3b77ef-c891-4a07-86e9-066c83c951de" /disk2      ext4    defaults          0 0

Run the following command to read the fstab file and automatically mount file systems based on the configurations in the file. If the command output does not contain errors, the fstab file is correctly configured.

mount -a

Step 8: New storage location for Docker Engine

Modify the Docker daemon configuration file to reflect the new storage path:

vi /etc/docker/daemon.json

Add or update the following content:

{
  "data-root": "/disk2/docker"
}

Save and exit the file.

Restart Docker service:

systemctl restart docker

Run the following command again to confirm that the storage directory has changed:

docker info | grep "Docker Root Dir"

If the output shows /disk2/docker, the configuration is successful.

Step 9: Move existing data

To move Docker data from the default directory to a new location while retaining the existing data, proceed with the following commands:

systemctl stop docker
mv /var/lib/docker /disk2/docker
systemctl start docker

To confirm that everything is OK, you can run docker ps and verify that the containers started in Step 4 are running.

Step 10: Check the current disk usage:

df -h

As you can see from the output below, the space used by Docker (approximately 3.3G) is now being stored in the /dev/sdb partition.

root@vbox:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            953M     0  953M   0% /dev
tmpfs           197M  1.2M  196M   1% /run
/dev/sda1        19G  5.7G   12G  33% /
tmpfs           984M     0  984M   0% /dev/shm
tmpfs           5.0M  8.0K  5.0M   1% /run/lock
/dev/sdb         15G  3.3G   11G  24% /disk2
tmpfs           197M   88K  197M   1% /run/user/1000
overlay          15G  3.3G   11G  24% /disk2/docker/overlay2/5ce0660852449f15e51c7976a8d7a095ff828d7cbde18899f41057b3fa84a7eb/merged
overlay          15G  3.3G   11G  24% /disk2/docker/overlay2/8a8b573a91b37136ad195d8e77f49aa899646de13cc018642ff37a0fd682fa5a/merged
overlay          15G  3.3G   11G  24% /disk2/docker/overlay2/a86a940a3c481f91605aa2b76f6352b0c327658eee7e47242a7ca7991119038b/merged

Conclusion

Configuring Docker’s storage location can improve performance and optimize storage management. This is especially useful when running Docker on a Raspberry Pi with an SD card, allowing you to store Docker data on an external disk instead. By following these steps, you can ensure a more efficient and reliable storage solution for Docker in Linux environments.