1.3 Docker Volumes
1. Creation of Volume
Following methods are available to persist data in docker
1.1 Mount a folder
If you need to persist data, you can mount a volume using the -v
flag:
You can mount a folder in a host PC to the container as a volume
docker run -it -v /host/path:/container/path alpine-bash
1.2 Named Volume
First create the volume and then mount it.
docker volume create named-volumedocker run -dit --name ubuntu-named-vol --volume named-volume:/volume-mounted-from-host ubuntu:latest
# or
docker run -dit --name ubuntu-named-vol -v named-volume:/volume-mounted-from-host ubuntu:latest
1.3 Create a named volume on the fly
Docker creates the named volume on the fly and mount it. How
sudo docker run -dit --name ubuntu-named-vol –mount source=myvolume target=/volume-mounted-from-host ubuntu:latest
# or
docker run -dit --name ubuntu-named-vol -v named-volume:/volume-mounted-from-host ubuntu:latest
1.4 Additional Tips
Mount a volume onto an existing directory
You can also mount a volume for an existing data volumn / folder inside the container. Following will create a container and add the data volume at /var
, a directory that is found in the base image.
docker run -dit --name ubuntu-named-vol -v named-volume:/var ubuntu:latest
2. Shared Volume
To share a volume between two Docker containers, you can create a Docker volume and then mount it to both containers. This allows the containers to read from and write to the same storage location, enabling them to share data.
2.1 Method 01
1. Create a Docker Volume:
First, create a Docker volume that will be shared between the containers.
docker volume create shared_volume
This creates a named volume called shared_volume
.
2. Run the First Container with the Volume:
Run the first container and mount the volume to a specific directory inside the container.
docker run -d --name container1 -v shared_volume:/shared_data my_image
-d
: Runs the container in detached mode.--name container1
: Names the containercontainer1
.-v shared_volume:/shared_data
: Mounts theshared_volume
to the/shared_data
directory inside the container.my_image
: The name of the Docker image to run.
3. Run the Second Container with the Same Volume:
Now, run the second container and mount the same volume to a directory inside it.
docker run -d --name container2 -v shared_volume:/shared_data my_image
This mounts the same shared_volume
to the /shared_data
directory inside the second container.
Explanation:
- Both containers (
container1
andcontainer2
) now share the sameshared_volume
mounted to the/shared_data
directory. - Any data written to
/shared_data
by one container will be accessible to the other container, allowing them to share files and data.
Example Scenario:
If container1
writes a file to /shared_data/myfile.txt
, container2
will be able to read that file from the same location.
This is useful in various scenarios, such as when you want two services running in separate containers to share configuration files, logs, or any other data.
2.2 Method 02
# Create a volume on the flydocker run -it --name=Container1 -v named-volume:/shared-data-vol ubuntu
# Now, create another container that mounts the same volume from Container1 (using --volumes-from)docker run -it --name=Container2 --volumes-from Container1 ubuntu# This will show the volume `named-volume` (from Container1) inside Container2
--volumes-from <source_container>
: Specifies the container from which volumes should be mounted. This is the container that has the volumes you want to share.
2.3 Detach / Remove a Volume
To detach a volume from a Docker container, you generally need to stop the container first and then remove the container. If you just want to detach the volume without removing it, you can do this by removing the container without deleting the associated volume. Steps are described below:
1. Stop the Container (Optional):
If the container is running, stop it first:
docker stop <container_name_or_id>
2. Remove the Container Without Removing the Volume:
When removing the container, you can use the --volumes
or -v
flag to delete the associated volumes. To detach the volume and keep it intact, you should omit this flag:
docker rm <container_name_or_id>
This command will remove the container but will leave the volume intact.
3. Re-Attach the Volume to a New Container (Optional):
If you want to use the same volume with another container, you can re-attach it when running a new container:
docker run -d --name new_container -v shared_volume:/shared_data my_image
Example:
Let’s say you have a container named container1
using a volume called shared_volume
:
-
Stop the Container:
Terminal window docker stop container1 -
Remove the Container (Without Removing the Volume):
Terminal window docker rm container1 -
Re-Attach the Volume to Another Container:
Terminal window docker run -d --name container2 -v shared_volume:/shared_data my_image
Note:
-
If you use the
docker rm -v <container_name_or_id>
command, it will remove the container and any anonymous volumes associated with it, but named volumes likeshared_volume
will not be deleted unless explicitly removed withdocker volume rm
. -
The volume itself persists until you explicitly delete it with:
Terminal window docker volume rm shared_volume
This approach allows you to detach a volume from one container and re-attach it to another, keeping the data intact and available.
2.4 Attach a Volume
However, you can achieve the desired result by creating a new container with the same configuration as the old one, including the new volume.
1. Create a New Container with the Additional Volume
To simulate adding a volume to an existing container, you can create a new container based on the old one’s configuration and include the new volume mount.
1. Retrieve the Configuration of the Existing Container:
First, get the details of the existing containe**r. You’ll need the image name and any necessary configuration details like environment variables, port mappings, etc. Use the following command to get the configuration:
docker inspect <existing_container_name_or_id>
Look for relevant details such as environment variables, ports, and volume mounts in the output.
2. Run a New Container with the Same Configuration and the New Volume:
Use the information obtained from the inspect c**ommd to create a new container with the additional volume.
docker run -d \ --name <new_container_name> \ --env <env_vars> \ -p <host_port>:<container_port> \ -v <new_host_volume_path>:<new_container_volume_path> \ <image_name>
Replace:
<new_container_name>
: a name for the new container.<env_vars>
: environment variables if needed (format:VAR=value
).<host_port>:<container_port>
: port mappings if needed.<new_host_volume_path>
: the new volume path on the host machine.<new_container_volume_path>
: the path inside the container where the new volume will be mounted.<image_name>
: the Docker image used by the existing container.
Make sure to include any other configurations that were present in the old container.
3. Copy Data (if necessary):
If you need to transfer data from the old container to the new one, you might need to manually cop**y fes. You can use docker cp
to copy files between containers or between the host and containers.
docker cp <existing_container_name_or_id>:<path_in_container> <path_on_host>docker cp <path_on_host> <new_container_name>:<path_in_container>
4. Verify the New Container:
Check if the new container is running correctly and verify the volume mount:
docker inspect <new_container_name> | grep Mounts -A 10
5. Remove the Old Container (optional):
Once you’ve confirmed that the new container is working as expected, you can remove the old container if it’s no longer needed:
docker rm <existing_container_name_or_id>
This method essentially involves replicating the existing container with the addition of the new volume. While it’s not a direct modification of the existing container, it achieves the same result by creating a new container with the desired configuration.
3. Additional Tips:
You can list all your Docker volumes using:
docker volume ls
To get more details about the shared volume:
docker volume inspect shared_volume
This will show you where the volume is stored on your host system and other details.
4. Read Only Volumes
To map a volume in Docker where changes to a host folder do not affect the corresponding folder inside the container, you need to use a read-only bind mount. This ensures that the container can read from the host folder but cannot modify it, and changes on the host do not reflect in the container.
Here’s how to do it:
docker run -v /host/folder:/container/folder:ro <image_name>
/host/folder
: The directory on your host machine./container/folder
: The directory inside the container.:ro
: Stands for “read-only”. This flag makes the bind mount read-only inside the container.
Example:
docker run -v /home/user/data:/app/data:ro my-container
In this example:
/home/user/data
is the folder on your host./app/data
is the folder inside the container.:ro
makes the/app/data
folder read-only in the container, preventing changes inside the container from affecting the host.
This setup ensures that the container can read from the host folder, but changes to the host folder will not automatically sync to the container during runtime. However, any updates in the host folder before the container starts will be reflected when it starts.
5. Anonymous Volume
In Docker, an anonymous volume is a type of volume that is created automatically by Docker without a specific name. These volumes are used primarily when you want to persist data outside the container’s filesystem but don’t need to reference the volume by name later.
5.1 Key Characteristics of Anonymous Volumes
1. No Explicit Name: Unlike named volumes, anonymous volumes are not given a specific name by the user. Docker generates a unique name for them automatically.
2. Persistence: The data stored in an anonymous volume persists even after the container is removed. However, since the volume doesn’t have a name, it can be difficult to locate or reuse manually.
3. Automatic Creation: Docker creates anonymous volumes when you use the VOLUME
instruction in a Dockerfile or when you bind a directory inside a container without specifying a host path.
5.2 Usage Example
docker run -v /container/data busybox
In this example:
-v /container/data
creates an anonymous volume mounted to the/container/data
directory inside the container.- Docker creates and manages this volume automatically.
5.3 Listing Anonymous Volumes
You can list all volumes (including anonymous ones) with:
docker volume ls
5.4 Identifying Anonymous Volumes
Anonymous volumes have randomly generated names like 5a2e85b1a5dfd10e2b9ef77d497
.
5.5 Data Persistence
Even if you remove the container, the data in this anonymous volume will persist until the volume itself is removed. However, since it’s anonymous, the volume is hard to reuse without its randomly generated name.
5.6 Clean-Up
Since anonymous volumes can accumulate and consume disk space over time, you might want to clean them up using:
docker rm -f <container_id>docker volume prune
This command removes all unused volumes, including anonymous ones no longer referenced by any container.
5.7 Use Cases
Anonymous volumes are handy when you need to persist data temporarily or for single-use containers, without worrying about volume management afterward. For long-term or shared data storage, named volumes are typically preferred.