Share Same resource in multiple Container in docker - docker

I need to setup one container volume use to multiple container.
for example:
Container 1(web app1): volume path -v /var/www/html/
Container 2 (web app2): volume path -v /var/www/html/
Container 3(Commaon Files): volume path -v /var/www/html/
I need to setup Container-3 Common file use other two Containers.
How can I Achive this.

You should name your volumes so you can mount them by name instead of by container. So:
docker run -d --name web1 -v web1-html:/var/www/html web-img
docker run -d --name web2 -v web2-html:/var/www/html web-img
docker run -d --name common -v web1-html:/var/www/web1/html \
-v web2-html:/var/www/web2/html your-img
With the volumes created today from your two web apps, you'll see them listed with a guid under docker volume ls. By giving them a name, you can easily reused those volumes in other containers.

Related

Docker shared volumes create and attach problem

I've a question about docker shared volumes.
I know that if I run a container with -v option I create a volume that I can share to another container with --volumes-from:
docker run -d -v DataVolume1:/datavolume1 --name container1 image1:v1.0.0
docker run --name container2 --volumes-from container1 image2:v1.0.0
But I cannot understand the full behaviour of this. It seems like volume from container 1 is a master and the same volume in container 2 is a slave. So container 2 can write and container 1 read or only the opposite?
Why I cannot use -v option on all my container like that?
docker run -d -v DataVolume1:/datavolume1 --name container1 image1:v1.0.0
docker run -d -v DataVolume1:/datavolume1 --name container2 image2:v1.0.0
or create a volume with:
docker volume create --name DataVolume1
and then attach to the two container with:
docker run -d -v DataVolume1:/datavolume1 --name container1 image1:v1.0.0
docker run -d -v DataVolume1:/datavolume1 --name container2 image2:v1.0.0
Is there some trouble because each -v recreate the volume and cut the link with the previous container? Or something other?
Because with two "docker run -v" I could also specify different mounting path for the same volume, so if it work for me is better, but I never see anyone use this way so what's the problem?
Thanks in advance!

Difference between -volume and -volumes-from in Docker Volumes

What is the exact difference between the two flags used in docker volume commands -v and --volumes-from. It seems to me that they are doing the same work, consider the following scenario.
First lets create a volume named myvol using command:
$ docker volume create myvol
Now create and run a container named c1 that uses myvol and get into his bash:
$ docker run -it --name c1 -v myvol:/data nginx bash
Lets create a file test.txt in the mounted directory of the container as:
root#766f90ebcf37:/# touch /data/test.txt
root#766f90ebcf37:/# ls /data
test.txt
Using -volume flag:
Now create another container named c2 that also uses myvol:
$ docker run -it --name c2 -v myvol:/data nginx bash
As expected, the new generated container c2 also have access to all the files of myvol
root#393418742e2c:/# ls /data
test.txt
Now doing the same thing with --volumes-from
Creating a container named c3 using volumes from container c1
$ docker run -it --name c3 --volumes-from c1 nginx bash
This will result the same thing in c3:
root#27eacbe25f92:/# ls /data
test.txt
The point is if -v and --volumes-from are working the same way i.e. to share data between containers then why they are different flags and what --volumes-from can do that -v cannot do?
The point is if -v and --volumes-from are working the same way i.e. to share data between containers
-v and --volumes-from are not working the same way, but with both of them you can share data between containers.
what --volumes-from can do that -v cannot do?
E.g. it can connect to another containers volumes without knowing how volumes are named and you do not specify path. You are able to add suffixes to containers ID's, with permissions like :ro or :rw.
More details here - Mount volumes from container (--volumes-from) section
The other question is what -v can do that --volumes-from cannot do?
E.g. it can mount named volumes, you can mount host directories or tmpfs (this one you cannot share between containers). In --volume-from you cannot share data with host directly.
The conclusion is: the purpose of --volume is to share data with host. (here you can find more use cases).
The purpose of --volumes-from is to share the data between containers.
They both works nice together.

How to properly share a folder between few docker containers in read mode?

I have Docker installed in top of a CentOS system.
I tried to use volume but each new container is deleting (or hidding) the content of the folder to share.
My volume is always empty after a Docker run.
In order to create my containers, I use
docker run -dit --name $CONTAINER_NAME -p $PORT:8080 \
-v $VOLUME_PATH:/opt/conf/ \
$IMAGE_NAME
I aim at sharing a folder from the host between few Docker containers (to READ) AND I want also to write into this folder from the host.
What is an elegant way to do that ?
One solution is to use Data Volume Containers.
First, create a data volume container
docker run -d --name <data-volume-name> -v /<data-volume-name> ubuntu
You can add any data you want in this container.
Create your containers that will share by using the option volume-from
Let's create container foo and container bar using the shared datacontainer :
docker run -it --name foo --volumes-from=<data-volume-name> ubuntu
docker run -it --name bar --volumes-from=<data-volume-name> centos
Enjoy yourself
Each container in my example is mapped to the root folder.
From either bar or foo you can see /, in the filesytem.
You can also use volume field.
Create a volume
docker volume create --name <volume-name>
Create containers foo and bar that witl be mapped to the volume
docker run -dit --name foo -v test-volume:/path/in/container/ <image-name>
docker run -dit --name bar -v test-volume:/path/in/container/ <image-name>
Each container that will write in the volume will be visible by other.

How to re-mount a docker volume without overriding existing files?

When running Docker, you can mount files and directories using the --volume option. E.g.:
docker run --volume /remote ./local myimage
I'm running a docker image that defines VOLUMESs in the Dockerfile. I need to access a config file that happens to be inside one of the defined volumes. I'd like to have that file "synced" on the host so that I can edit it. I know I could run docker exec ..., but I hope to circumvent that overhead for only editing one file. I found out that the volumes created by the VOLUMES line are stored in /var/lib/docker/volumes/<HASH>/_data.
Using docker inspect I was able to find the directory that is mounted:
docker inspect gitlab-runner | grep -B 1 '"Destination": "/etc/gitlab-runner"' | head -n 1 | cut -d '"' -f 4
Output:
/var/lib/docker/volumes/9c233c085c36380c6c33035222c16e5d061368c5060cc81dda2a9a713a2b2b3b/_data
So the question is:
Is there a way to re-mount volumes defined in an image? OR to somehow get the directory easier than my oneliner above?
EDIT after comments by zeppelin I've tried rebinding the volume with no success:
$ mkdir etc
$ docker run -d --name test1 gitlab/gitlab-runner
$ docker run -d --name test2 -v ~/etc:/etc/gitlab-runner gitlab/gitlab-runner
$ docker exec test1 ls /etc/gitlab-runner/
certs
config.toml
$ docker exec test2 ls /etc/gitlab-runner/
# empty. no files
$ ls etc
# also empty
docker inspect shows correctly that the volume is bound to ~/etc, but the files inside the container at /etc/gitlab-runner/ seem lost.
$ docker run -d --name test1 gitlab/gitlab-runner
$ docker run -d --name test2 -v ~/etc:/etc/gitlab-runner gitlab/gitlab-runner
You've got two different volume types there. One I call an anonymous volume (a very long uuid visible when you run docker volume ls). The second is a host volume or bind mount that maps a directory on the host directly into the container. So each container you spun up is looking at different places.
Anonymous volumes and named volumes (docker run -d -v mydata:/etc/gitlab-runner gitlab/gitlab-runner) get initialized to the contents of the image at that directory location. This initialization only happens when the volume is empty and is mounted into a new container. Host volumes, as you've seen, only get the contents of the host filesystem, even if it's empty at that location.
With that background, the short answer to your question is no, you cannot mount a file inside the container back out to your host. But you can copy the file out with several methods, assuming you don't overlay the source of the file with a host volume mount. With a running container, there's the docker cp command. Personally, I like:
docker run --rm -v ~/etc:/target gitlab/gitlab-runner \
cp -av /etc/gitlab-runner/. /target/.
If you have a named volume with data you want to copy in or out, you can use any image with the tools you need to do the copy:
docker run --rm -v mydata:/source -v ~/etc:/target busybox \
cp -av /source/. /target/.
Try to avoid modifying data inside a container from the host directly, much nicer is when you wrap your task into another container that you then start with "--volumes-from" option when possible in your case.
Not sure I understood your problem, anyway, as for the documentation you mention,
The VOLUME instruction creates a mount point with the specified name
and marks it as holding externally mounted volumes from native host or
other containers. [...] The docker run command initializes the newly
created volume with any data that exists at the specified location
within the base image.
So, following the example Dockerfile , after having built the image
docker build -t mytest .
and having the container running
docker run -d -ti --name mytestcontainer mytest /bin/bash
you can access it from the container itself, e.g.
docker exec -ti mytestcontainer ls -l /myvol/greeting
docker exec -ti mytestcontainer cat /myvol/greeting
Hope it helps.

How to add directory to existing Data container in Docker?

I have made a data container in Docker with the directory /tmp:
sudo docker create -v /tmp --name datacontainer ubuntu
I will add another directory to this existing data container like /opt.
How can i do this?
You cannot add a new data volume to an existing (created or running) container.
With docker 1.9+, you would use instead docker volume create:
docker volume create --name my-tmp
docker volume create --name my-opt
Then you can mount those volumes to any container you want (when you run those containers, not when they are already running)
docker run -d -P \
-v my-tmp:/tmp \
-v my-opt:/opt \
--name mycontainer myimage

Resources