Containers do not persist the generated data when they are removed; hence, the data will be lost. The storage of data permanently is achieved in three different ways:
- Volumes
- Bind mounts
- In-memory storage
Volume: It is a directory created by the docker engine on the host. It is isolated from the host filesystem. It is fully managed by docker engine.
Bind mount: It is a directory on the host that is managed by the host filesystem. This directory is not isolated from the host filesystem.
In-memory storage: It is a temporary memory stored on the host volatile memory. This memory is mounted on a directory inside the container filesystem.
$ docker volume create <volume-name>
The command creates a volume with the provided name.
$ docker volume create data
A volume does not have to be created by this command. It is create the first time it is mounted in the container filesystem.
The command displays detailed information about a volume. This information is in JSON format.
$ docker volume inspect <volume-name>
$ docker volume inspect data
The command lists all known volumes.
$ docker volume list
Options:
-q : List only volume names
The command removes the specified volume.
$ docker volume rm <volume-name>
$ docker volume rm data
A volume that is used by a container (in running or stopped/exiting states) cannot be removed. The option -f can be used to force the removal of used volume, but this operation may lead to loss of data.
To remove all unused volumes
$ docker volume prune
Options:
-f : Do not prompt for confirmation
Volumes can be mounted (attached) inside the containers to store data. The mounting of a volume is specified by the -v option when running a container.
The parameter of the -v option has the form: <volume-name>:<container-directory> The volume-name is mounted on the container folder located inside the container.
The container directory should be defined using absolute paths (i.e. path starts with /).
The container directory is created if it does not exist.
$ docker volume create data
$ docker run -it --rm -v data:/app alpine /bin/sh
Multiple container may use one volume at the same time. This allows sharing data between containers. However, this may lead to data inconsistency if two containers try to write to the a volume at the same time.
To avoid this issue, one container is allowed to write to the volume and the remaining containers can read only.
$ docker run -it --rm -v data:/app --name writer alpine /bin/sh
$ docker run -it --rm -v data:/app:ro --name reader alpine /bin/sh
The readonly constraint is indicated by the "ro" option.
The VOLUME instruction creates mount points (directories) inside the container. The volume is not defined in the Dockerfile, it is created when the container is run.
# Dockerfile
VOLUME ["/App/Sample"]
$ docker build -t myimage .
$ docker run -it --rm -v sample:/App/Sample myimge /bin/bash
$ docker run -it --rm myimge /bin/bash
$ docker volume ls
In the second run, an unnamed volume is created and mounted on /App/Sample
Bind mounts are directories on the host filesystem that are mounted inside the container. They play the same role as volumes with few differences.
Bind mounts are specified using the --mount option in the run command: -v <host-directory>:<container-directory>
$ docker run -d -it --name devtest -v /Users/User/Sample:/App centos
$ docker run -d -it --name devtest -v "$(pwd)"/Sample:/App centos
The $(pwd) is a shell command that is substituted by the path of the current working directory.
The target directory is created if it does not exist already in the container.
This allows the creation of an in-memory filesystem (RAM) on the host and attach it to the container filesystem.
The in-memory storage is a temporary storage that can be deleted by the host if it is unused for a long time.
The in-memory storage uses the tmpfs that works only on Linux based-systems.
$ docker run --rm --mount type=tmpfs,dst=/tmpme,tmpfs-size=5m alpine mount -t tmpfs