Docker Volumes
Volumes are used for persistent file storage.
They allow you to store contents of directories outside of containers, and in turn independently of their state.
This means that when you delete and recreate them (e.g. because you have updated them), files stored in volumes are kept.
Volumes may also be used for sharing files between multiple containers.
This setup needs to be supported by the software running in both of them, otherwise you should expect data corruption to happen, purely out of them overwriting each other’s work.
Based on the volume driver in use, the files may be stored at a network location, they may be encrypted, compressed, and other possibilities may become available with them.
The official documentation can be read here.
Types of volumes
The volumes are primarily differentiated based on how can you refer to them.
Anonymous volumes are ones you cant refer to.
They are created when it is defined in the container image that certain directories should be stored in a volume, but the user did not set up a named volume for them.
Although they are not automatically removed along with the container, recreating the container will result in new anonymous volumes being used.
Their main purpose is simply to indicate which directories should be persisted when the user wants that, but still not interfere when the user intends to create a totally temporary container.
Named volumes can be referred to by their names, and they will be reused as expected when the container is recreated.
There are also bind mounts, which are not actually volumes, but it is useful to mention them here.
They will persist your data like a named volume, but Docker will not list them among volumes.
You define them by specifying a filesystem path instead of a volume name.
Volume syntax
There are 2 syntaxes available for specifying volumes: the “volume” syntax and the “mount” syntax.
More details about the volume syntax can be read here.
The “volume” syntax
The “volume” syntax is more consice, but it allows less detailed configuration.
All configuration parameters are written on 1 line, in which 3 fields are distinguished, each of them separated by the :
character.
- The first field is the name of the volume. This must be unique on the host where Docker is running. It is omitted for anonymous volumes.
- The second field is the path inside of the container where the volume will be mounted.
- The third field is an optional list of options.
Example volume specification with the “volume” syntax:
Volume type | Volume specification |
---|---|
named volume | myapp_data:/var/lib/myapp/ |
read only named volume | myapp_data:/var/lib/myapp/:ro |
anonymous volume | /var/log/myapp/ |
read only anonymous volume | /var/log/myapp/:ro |
The “mount” syntax
The “mount” syntax may be easier to understand, but it is much longer.
It consists of comma separated key-value pairs.
Keys are source
, destination
, type
, readonly
and volume-opt
, several of which has a shortened version.
volume-opt
makes it possible to pass configuration options to the selected volume driver.
Example volume specification wih the “mount” syntax:
Volume type | Volume specification |
---|---|
named volume | type=volume,source=myapp_data,destination=/var/lib/myapp/ |
read only named volume | type=volume,source=myapp_data,destination=/var/lib/myapp/,readonly |
anonymous volume | type=volume,destination=/var/lib/myapp/ |
read only anonymous volume | type=volume,destination=/var/lib/myapp/,readonly |
Managing volumes
Volumes are managed by subcommands of the docker volume
command. These are also documented here.
Below you will find a brief summary of the volume management commands, but you may also read the official tutorial here.
Creating volumes
Volumes can be created with the docker volume create [options] [name]
command.
Omitting the name
parameter will result in an anonymous volume being created.
A specific driver and driver options can be set with the --driver
and --driver-opts
options.
Listing volumes
Existing volumes can be listed with the docker volume list
command.
Changing volume settings
Changing volume settings after creation is not possible without recreating it.
Be sure to backup all data in the volume before deleting it!
Deleting volumes
You can delete a volume with the docker volume remove <name>
command.
Deletion is permanent! All data will be lost!
Volume drivers
The driver of a volume and its parameters can be only set at creation, they cannot be changed later.
Volume driver specific parameters can be specified with the volume-opts
key of the “mount” syntax.
Detailed use of volume drivers are documented here.
The local
driver
This driver will use the capabilities of the Host system for finding a place for the volume’s contents.
The specifics can be configured in driver options,
which for this driver are documented here.
On Windows, driver options are not supported, and volume data can only be stored on already mounted filesystems.
On Linux based Host systems, the parameterization is similar to using the mount
command.
The parameters will be handed over to the mount
command, which means any type of filesystem can be used that has a mount wrapper installed.
The following parameters are used:
Parameter | Meaning |
---|---|
device | Location of backing data. Usually path of a block device in case of local filesystems. See the section “Indicating the device and filesystem” in the man page of the mount utility for details |
type | Type of filesystem. See the documentation of --types in the man page of the mount utility for details |
o | Comma separated list of mount options. See the documentation of --options in the man page of the mount utility for details |
On configuration of the local
driver on Linux systems further explanation can be read here.
Note that the page mentions specifically “block devices”, but actually it is relevant independently to the kind of filesystem you use.
It is possible to create named volumes that also work like a bind mount.
To achieve that, you will need to use the volume-opt=type=none
and volume-opt=o=bind
parameters, and also specifiy a bind destination with volume-opt=device=...
.
Example: --mount "type=volume,source=myapp_data,destination=/var/lib/myapp,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/srv/myapp/data"
.
It is important to note that the volume data will not be stored at the bound location, it is merely available at that path. Data is stored at the original location, and takes up storage space there, which is unchanged from conventional named volumes.
3rd party drivers
There are plenty of volume drivers that are not bundled with Docker, but can be installed separately if needed. Some of them are listed on this page.