Backing Up and Restoring Docker Volumes

The default persistent data storage method for Docker is volumes. Unfortunately, it’s not immediately obvious how to back up that data.

Let’s take a look at the current running containers:

#docker ps

CONTAINER ID   IMAGE                          COMMAND                  CREATED       STATUS                    PORTS                                                                                            NAMES
ce1909aeda8e   photoprism/photoprism:latest   "/entrypoint.sh /opt…"   8 hours ago   Up 32 minutes             0.0.0.0:2342->2342/tcp, :::2342->2342/tcp                                                        photoprism
9409cd88f6a0   hkotel/mealie:latest           "/bin/sh -c $MEALIE_…"   8 hours ago   Up 32 minutes (healthy)   0.0.0.0:49155->80/tcp, :::49155->80/tcp                                                          Mealie
fd5200b925ca   portainer/portainer-ce:2.9.3   "/portainer"             8 hours ago   Up 33 minutes             0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp   portainer

Now perform an inspect on the one you’d like to save the data from:

#docker inspect photoprism

"Mounts": [
            {
                "Type": "volume",
                "Name": "photoprism_data",
                "Source": "/var/lib/docker/volumes/photoprism_data/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            },

The data lives in the “Source” location. Let’s make a compressed tarball out of it:

#tar cvzf /var/lib/docker/volumes/photoprism_data/_data/* /mnt/backups/photoprism_data_backup.tar.gz

Restoring Volumes

Next, we’ll restore that backed up data using bind mounts. This is NOT the official docker way of doing things, but I find that the official docker way requires making temporary containers and long command strings that are easily confusing. We’ll use Portainer and regular directories.

First, create your new data directory we’ll use and extract the backup:

#mkdir /home/docker/photoprism_data
#tar xvzf photoprism_data_backup.tar.gz /home/docker/photoprism_data/

Next, head to Portainer and replace your docker volumes with bind-mounts:

Notice this particular container uses 3 different volumes. You would need to have 3 different backups from the first section and point them to 3 different binds on the main filesystem. By doing this, however, you’ll never have to guess where your data is again. It will always be stored at this location.

If you need to spin up a new instance of Photoprism, for example, just spin it up with these bind-mounts and your data will be immediately restored.

EVEN BETTER, if these bind-mounts point to an NFS share on a NAS, you automatically have them backed up in real-time.

The Official Docker Way

Just in case you like doing things the hard way, here’s a link to the official Docker documentation. It involves creating temporary containers to backup and restore your volume data:

https://docs.docker.com/storage/volumes/#backup-restore-or-migrate-data-volumes