Docker data persistence management

Manage data persistence with docker

view on github

Options for data persistence

Bind-mounts

  • always use the --mount syntax instead of -v when using bind mounts
  • host paths and container paths must always be absolute paths (use command substitution with realpath for convenience)
  • host mounted directory contents will replace bind mount contents in container (CAUTION)

✔️ Use bind-mounts with docker containers

# create container <name> from <image> and mount host <hpath> to container <cpath>, read-only
docker container run --mount type=bind,source=<hpath>,target=<cpath>,ro=true --name <name> <image>

# same as above plus : override CMD/ENTRYPOINT directive with interactive shell/pseudo tty
docker container run --mount type=bind,source=<hpath>,target=<cpath>,ro=true --name <name> -i -t <image> /bin/sh

Volumes

  • always use the --mount syntax instead of -v when using volumes as well (only option supported by docker service)
  • easier to back up or migrate, manageable using Docker CLI commands, shared among multiple containers, higher performance on non-Linux
  • volumes do not increase the size of the containers using them, and their contents are persisted once the container is removed
  • volume name must be unique on a given host machine, and they are automatically created on invocation if they do not exist

✔️ Manage volumes

# create volume
docker volume create <volume>

# remove volume
docker volume rm <volume>

# inspect volume
docker volume inspect <volume>

✔️ Volume contents is stored on the host's file system in the "Mountpoint" location of the docker volume inspect output

✔️ Use volumes with docker containers

# create container <name> from <image> and mount volume <volume> to container <cpath>
# override CMD/ENTRYPOINT directive with interactive shell/pseudo tty
docker run --rm --mount type=volume,source=<volume>,target=<cpath> --name <name> -i -t <image> /bin/sh

✔️ Use volumes with docker services

# use service name <name>
# start 5 replicas (containers) from the image <image>, mount <volume> to all containers <cpath>
docker service create --name <name> --replicas=5 --mount type=volume,source=<volume>,target=<cpath> <image>

✔️ In the above case, each container in the service will access its own local volume (the default volume driver local does not support shared storage)

Data backup with Docker

✔️ Create a container with a volume mount

# create container <name1> from <image>
# mount volume <volume1> to container <cpath1>
# override CMD/ENTRYPOINT directive with <command>
docker container run --name <name1> --mount type=volume,source=<volume1>,target=<cpath1> <image> <command>

✔️ Populate <volume1> with data by accessing container <name1>

✔️ Create a dedicated backup container

# create unnamed disposable container from busybox
# mount volume <volume1> to container <cpath1>
# mount host <hpath> to container <cpath2>
# run a tar command to create an archive of <cpath1> content into <cpath2>/<archive>
docker container run --rm --volumes-from <name1> --mount type=bind,source=<hpath>,target=<cpath2> busybox tar -cvf <cpath2>/<archive> <cpath1>

✔️ As a result, contents of <volume1> will be saved in <hpath>/<archive> on the host

Data restoration with Docker (reverse operation)

✔️ Create a container with a new volume mount

# create container <name2> from <image>
# mount volume <volume2> to container <cpath1>
# override CMD/ENTRYPOINT directive with <command>
docker container run --name <name2> --mount type=volume,source=<volume2>,target=<cpath1> <image> <command>

✔️ Create a dedicated restoration container

# create unnamed disposable container from busybox
# mount volume <volume2> to container <cpath1>
# mount host <hpath> to container <cpath2>
# run a tar command to extract <cpath2>/<archive> in <cpath1>
docker container run --rm --volumes-from <name2> --mount type=bind,source=<hpath>,target=<cpath2> busybox sh -c "cd <cpath1> && tar -xvf <cpath2>/<archive>"

✔️ As a result, the contents of <archive> has been restored to <volume2>