Docker start a container with already created volume - docker

How would I go about starting a container with a volume that's already created? I have a volume for example named 'data' and 'docker volume ls' will show this. Now I need to start a container by attaching this existing volume.

Mounting a Data Volume
To mount a data volume to a container add the --mount flag to the docker run command. It adds the volume to the specified container, where it stores the data produced inside the virtual environment.
To run a container and mount a data volume to it, follow the basic syntax:
docker run --mount source=[volume_name],destination=[path_in_container]
Replace [path_in_container] with the path where you want to place the data volume in the container. Everything stored in that directory automatically gets saved on the data volume on the host as well.
For example, to launch an Ubuntu container and mount the data volume to it, run:
docker run -it --name=example1 --mount source=data,destination=/data ubuntu

Related

docker volume and VOLUME inside Dockerfile

I'm confused with what is different between creating docker volume create my-vol and VOLUME ["/var/www"].
My understanding is:
1) docker volume create my-vol creates a persistent volume on our machine and each container could be linked to my-vol.
2) VOLUME ["/var/www"] creates a volume inside its container.
And when I create another container, I could link my-vol as follows:
when running a container
$ docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
At that time, if I added VOLUME ["/var/www"] in my Dockerfile, all data of this docker file will be stored in both myvol2 and /var/www?
The Dockerfile VOLUME command says two things:
If the operator doesn't explicitly mount a volume on the specific container directory, create an anonymous one there anyways.
No Dockerfile step will ever be able to make further changes to that directory tree.
As an operator, you can mount a volume (either a named volume or a host directory) into a container with the docker run -v option. You can mount it over any directory in the container, regardless of whether or not there was a VOLUME declared for it in the Dockerfile.
(Since you can use docker run -v regardless of whether or not you declare a VOLUME, and it has confusing side effects, I would generally avoid declaring VOLUME in Dockerfiles.)
Just like in ordinary Linux, only one thing can be (usefully) mounted on any given directory. With the setup you describe, data will be stored in the myvol2 you create and mount, and it will be visible in /var/www in the container, but the data will only actually be stored in one place. If you deleted and recreated the container without the volume mount the data would not be there any more.
There are two types of persistent storage used in Docker,the first one is Docker Volumes and the second one is bind mounts. The differebce between them is that volumes are internal to Docker and stored in the Docker store (which is usually all under /var/lib/docker) and bind mounts use a physical location on your machine to store persistent data.
If you want to use a Docker Volume for nginx:
docker volume create nginx-vol
docker run -d --name devtest -v nginx-vol:/usr/share/nginx/html nginx
If you want to use a bind mount:
docker run -d --name devtest -v [path]:/usr/share/nginx/html nginx
[path] is the location in which you want to store the container's data.

Docker volume: persist data on a remote host

https://docs.docker.com/storage/#more-details-about-mount-types
Good use cases for volumes
When you want to store your container’s data on a remote host or a cloud provider, rather than locally.
How is this accomplished with docker volume? Aren't docker volume under hosts's /var/lib/docker?
Could you give me an example of "docker volume create" of this and how it could be utilized?
Yes, volumes are created under /var/lib/docker/volumes/ so you need to link this volume with the folder you want to persist or where you have your data to persist.
Example:
You have your image named ImageExample and your project under /var/www/MyProject/.
First, you need to create new volume and assign a name.
$ docker volume create --name VolumeExample
# if you run: docker volume ls, they list all your volumes available
$ docker volume ls
DRIVER VOLUME NAME
local JbpmVolume1
local VolumeExample
Second, you have to link your new volume to a folder in your container.
$ docker run -v VolumeExample:/var/www/MyProject/ -p 8080:8080 MyImage
Where run is the command to create the container, -p is to map the local and host ports, MyImage is the image used in this example, VolumeExample is the volume created before and /var/www/MyProject/ is the example folder which you need to persist.
You can use this volume to store application configuration, database data or configuration too and so on. Maybe, depends on what you need to store, you can use bind mount or volumes or if your host is in linux, you can use tmpfs mounts.
As simple as that, you can read more about in docker webpage but basically this is how to work with a volume. Every time you stop/start or create/delete the container, the data in your volume will persist.
I do it in this way, because this is not the "happy path" you want. You have to mount before you store the data in the folder, because when you mount the volume, the folder will be empty because the volume is empty. If you have data in the folder before you mount the volume, the data will be not visible for you. So it depends on your project the way you will create the volume, but basically, with this two commands you mount the volume into the host container.

Bind-mount a host directory into a volume of a running docker container

Let's say that I start a docker container with a bind-mounted local folder:
docker run --rm -v /ux1/dmtest:/data -it ubuntu
Then, locally - not inside the container, I bind-mount a directory from another fs into /ux1/dmtest:
mkdir /ux1/dmtest/bm
mount --bind /ux0/bm /ux1/dmtest/bm
Now, from the container, I see /data/bm/ and I can write content to it, but this content will not be visible on the host on /ux0/bm.
Where is this content stored?
And is there any way to mount additional storage into a running docker container (this workaround clearly doesn't work)?
Mounts done after the fact won't be seen by the container due to mount namespaces that Docker uses. The files will be in the /ux1/dmtest directory that was in place before your second bind mount.
If you do want to use a bind mount, put it in place, and then start the docker daemon, and then your container will see it.

Mounting a single file from a Docker data volume in a Docker

I'm trying to mount a single file from a Docker volume in a container when using "docker run".
I've been able to mount an entire volume as a directory, e.g:
docker run -v my_volume:/root/volume my_container
I've also mounted single files from the physical machine, e.g:
docker run -v /usr/local/bin/docker:/usr/local/bin/docker
Is there a way?
Is there a way always destination path/file doesn't exist in the container, if you've created a named volume and a bind to its directory (similar to deprecated volumes_from)
docker run -v /var/lib/docker/volumes/my_volume/_data/MY_FILE.txt:/destination_folder/MY_FILE.txt
That's why when you create a named volume and run a service/container with docker run -v my_volume:/root/volume my_container, data is stored in /var/lib/docker/volumes/my_volume/_data

How Docker container volumes work even when they aren't running?

Take a typical data only Docker container:
FROM stackbrew/busybox:latest
RUN mkdir /data
VOLUME /data
Now I have seen a great deal of them that are run like this:
docker run -name my-data data true
The true command exits as soon as it runs, and so does the container. But surprisingly it continues to serve the volume when you connect it with another container via --volumes-from my-data.
My question is, how does that work? How does a stopped container still allow access in it's volumes?
Volumes in docker are not a top-level thing. They are "simply" part of container's meta-data.
When you have VOLUME in your dockerfile or start a container with -v, Docker will create a directory in /var/lib/docker/volumes* with a random ID (this is the exact same process as creating an image with commit except it is empty) and add that random ID to the container's metadata.
When the container starts, Docker will mount-bind the directory /var/lib/docker/volumes/* at the given location for that volume.
When you use volumes-from, Docker will just lookup the volume id and the location from an other container, running or not and mount-bind the directory at the set location.
Volumes are not linked with the runtime, it is just directories that are mounted.
* With newer versions, Docker now uses the vfs driver for storage and /var/lib/docker/volumes/ is used only for metadatas like size, create time, etc. The actual data are stored in /var/lib/docker/vfs/dir/<volume id>

Resources