Mounting a container volume into another container on a different path - docker

Is it possible to mount a volume from a container into another container on a different path? E.g.
contA exposes a volumen /source
mounting it in another container docker run --volumes-from contA -v /source/somedir:/etc/otherdir
I'm trying to use this with docker-compose and jwilder/nginx-proxy:
docker-compose.yml
myapp:
build: .
command: ./run.sh
volumes:
- /source
nginx:
image: jwilder/nginx-proxy
volumes_from:
- myapp
volumes:
- /source/vhost.d:/etc/nginx/vhost.d:ro
- /var/run/docker.sock:/tmp/docker.sock
links:
- myapp:myapp
If I'm trying so, I can't see my files at /etc/nginx/vhost.d:
$ docker-compose run nginx bash
root#f200c1c476c7:/app# ls -l
total 32
-rw-r--r-- 1 root root 1076 Apr 9 22:10 Dockerfile
-rw-r--r-- 1 root root 1079 Apr 9 22:10 LICENSE
-rw-r--r-- 1 root root 129 Apr 9 22:10 Procfile
-rw-r--r-- 1 root root 8385 Apr 9 22:10 README.md
-rw-r--r-- 1 root root 5493 Apr 9 22:10 nginx.tmpl
root#f200c1c476c7:/app# ls -l /etc/nginx/vhost.d
total 0
root#f200c1c476c7:/app# ls -l /source/nginx/
total 8
-rw-r--r-- 1 1000 staff 957 Apr 24 07:17 dockerhost.me

It doesn't seem possible, considering the syntax - v /host/path:/container/path is reserved for mounting a path from host (and not from another container)
That leaves you with the option of adding to your second container a symbolic link from /etc/otherdir to /source/somedir (which will exist because of the --volumes-from contA directive)

Related

docker-compose thinks file is a directory

Any ideas?
This service was starting before but now I get this '/etc/Caddyfile: is a directory' message and the service Exits.
$ docker-compose -f docker-compose-linux.yml up caddy
Starting server_applications_1 ... done
server_workspace_1 is up-to-date
server_php-fpm_1 is up-to-date
Starting server_caddy_1 ... done
Attaching to server_caddy_1
caddy_1 | http plugins loaded: git
caddy_1 | 2020/06/22 06:22:18 loading Caddyfile via flag: read /etc/Caddyfile: is a directory
server_caddy_1 exited with code 1
the caddy service dockerfile:
FROM zuohuadong/caddy:alpine
MAINTAINER Huadong Zuo <admin#zuohuadong.cn>
ARG plugins="cors"
WORKDIR /var/www/platform/public
CMD ["/usr/bin/caddy", "-conf", "/etc/Caddyfile"]
the Caddy service container yml: where CADDY_CUSTOM_CADDYFILE=./caddy/Caddyfile
volumes:
- ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile
and the Caddyfile is there in the right directory
...server/caddy$ ll
total 16
drwxrwxr-x 2 ubuntu ubuntu 4096 Jun 22 17:44 ./
drwxrwxr-x 11 ubuntu ubuntu 4096 Jun 22 15:55 ../
-rw-r--r-- 1 ubuntu ubuntu 1452 Jun 11 10:54 Caddyfile
-rw-r--r-- 1 ubuntu ubuntu 268 Jun 22 18:13 Dockerfile
$ docker-compose -f docker-compose-linux.yml up caddy
Starting server_applications_1 ... done
server_workspace_1 is up-to-date
server_php-fpm_1 is up-to-date
Starting server_caddy_1 ... done
Attaching to server_caddy_1
caddy_1 | http plugins loaded: git
caddy_1 | 2020/06/22 06:22:18 loading Caddyfile via flag: read /etc/Caddyfile: is a directory
server_caddy_1 exited with code 1
Can you try to mount directory instead of file in your docker compose.
volumes:
- ${CADDY_CUSTOM_CADDYFILE}:/etc
where CADDY_CUSTOM_CADDYFILE=full_Path_to/caddy/
you will still be able to use
CMD ["/usr/bin/caddy", "-conf", "/etc/Caddyfile"]

Docker for Windows: "Operation not permitted" trying to run an executable inside a container (bind-mount only)

I'm pretty sure that the last update of Docker for Windows has broken something.
Here is the thing. I have a custom image named toolbox, built from alpine, with a bounch of script inside it (bind-mount the local folder ./mnt/):
version: '3'
services:
# ...
toolbox:
build:
context: ./.docker/toolbox
restart: always
volumes:
- ./mnt/etc/periodic/daily:/etc/periodic/daily
Files have the right permissions:
/ # ls -la /etc/periodic/daily/
total 4
drwxrwxrwx 1 root root 4096 Mar 16 17:49 .
drwxr-xr-x 7 root root 4096 Jan 16 22:52 ..
-rwxr-xr-x 1 root root 332 Mar 1 23:57 backup-databases
-rwxr-xr-x 1 root root 61 Mar 1 23:51 cleanup-databases-backups
When I try to execute backup-databases I get the following error:
/ # /etc/periodic/daily/backup-databases /bin/sh:
/etc/periodic/daily/backup-databases: Operation not permitted
The strange thing is, if I create a script (from inside the container) it works:
echo "echo Hello" > /etc/periodic/daily/test
chmod +x /etc/periodic/daily/test
/etc/periodic/daily/test

How I can access docker data volumes on Windows machine?

I have docker-compose.yml like this:
version: '3'
services:
mysql:
image: mysql
volumes:
- data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=$ROOT_PASSWORD
volumes:
data:
And my mount point looks like: /var/lib/docker/volumes/some_app/_data and I want to access data from that mount point and I'm not sure how to do it on Windows machine. Maybe I can create some additional container which can pass data from docker virtual machine to my directory?
When I'm mounting folder like this:
volumes:
- ./data:/var/lib/mysql
to use my local directory - I had no success because of permissions issue. And read that "right way" is using docker volumes.
UPD: MySQL container it's just example. I want to use such behaviour for my codebase and use docker foe local development.
For Linux containers under Windows, docker runs actually over a Linux virtual machine, so your named volume is a mapping of a local directory in that VM to a directory in the container.
So what you got as /var/lib/docker/volumes/some_app/_data is a directory inside that VM. To inspect it you can:
docker run --rm -it -v /:/vm-root alpine:edge ls -l /vm-root/var/lib/docker/volumes/some_app/_data
total 188476
-rw-r----- 1 999 ping 56 Jun 4 04:49 auto.cnf
-rw------- 1 999 ping 1675 Jun 4 04:49 ca-key.pem
-rw-r--r-- 1 999 ping 1074 Jun 4 04:49 ca.pem
-rw-r--r-- 1 999 ping 1078 Jun 4 04:49 client-cert.pem
-rw------- 1 999 ping 1679 Jun 4 04:49 client-key.pem
-rw-r----- 1 999 ping 1321 Jun 4 04:50 ib_buffer_pool
-rw-r----- 1 999 ping 50331648 Jun 4 04:50 ib_logfile0
-rw-r----- 1 999 ping 50331648 Jun 4 04:49 ib_logfile1
-rw-r----- 1 999 ping 79691776 Jun 4 04:50 ibdata1
-rw-r----- 1 999 ping 12582912 Jun 4 04:50 ibtmp1
drwxr-x--- 2 999 ping 4096 Jun 4 04:49 mysql
drwxr-x--- 2 999 ping 4096 Jun 4 04:49 performance_schema
-rw------- 1 999 ping 1679 Jun 4 04:49 private_key.pem
-rw-r--r-- 1 999 ping 451 Jun 4 04:49 public_key.pem
-rw-r--r-- 1 999 ping 1078 Jun 4 04:49 server-cert.pem
-rw------- 1 999 ping 1675 Jun 4 04:49 server-key.pem
drwxr-x--- 2 999 ping 12288 Jun 4 04:49 sys
That is running an auxiliar container which has mounted the hole root filesystem of that VM / into the container dir /vm-root.
To get some file run the container with some command in background (tail -f /dev/null in my case), then you can use docker cp:
docker run --name volume-holder -d -it -v /:/vm-root alpine:edge tail -f /dev/null
docker cp volume-holder:/vm-root/var/lib/docker/volumes/volumes_data/_data/public_key.pem .
If you want a transparent SSH to that VM, it seems that is not supported yet, as of Jun-2017. Here a docker staff member said that.

Find out to which removed docker container a volume belonged to

Is there a way to associate existing docker volumes (located in /etc/docker/volumes) to containers?
One way to do this is to use docker inspect :conatiner_id but this assumes that the container exists. How can you find to which container the volume belonged to, in the scenario that the container does no longer exist?
Check docker volumes
$ ls -l /var/lib/docker/volumes/
total 72
drwxr-xr-x 3 root root 4096 Nov 14 14:27 0f801819cf76b04b6794163b65df5d649bd795e23f4fc778f78db9ac60a0180d
drwxr-xr-x 3 root root 4096 Nov 29 14:29 my-jenkins
For more info about your volume you can perform docker volume inspect but this tells you nothing about what's really inside your volume. The only way to know this is by going inside the volume-folder and check.
So I'll check "unamed" volume:
$ ls -l /var/lib/docker/volumes/0f801819cf76b04b6794163b65df5d649
bd795e23f4fc778f78db9ac60a0180d/_data
...
drwx------ 2 999 ping 4096 Nov 14 14:27 pg_tblspc
drwx------ 2 999 ping 4096 Nov 14 14:27 pg_twophase
drwx------ 3 999 ping 4096 Nov 14 14:27 pg_xlog
-rw------- 1 999 ping 88 Nov 14 14:27 postgresql.auto.conf
-rw------- 1 999 ping 20791 Nov 14 14:27 postgresql.conf
-rw------- 1 999 ping 37 Nov 14 14:27 postmaster.opts
Normally you should be able to link your volume to the old container you've used. You can check everything what's inside. There isn't a better way at the moment. This is actually the answer on your question but I'll give some more explanation to make it easier in the future.
The best way is to create named volumes. After deleting your container the volume will remain easy to recognize:
docker volume create --name my-jenkins
So in /var/lib/docker/volumes you'll see my-jenkins.
Now I start my jenkins container and link it with my named volume.
Everything which is in /var/jenkins_home will be stored in the named volume.
docker run -d -p 8080:8080 -v my-jenkins:/var/jenkins_home jenkins
I'll create a job in jenkins with the name firstjob. You'll see this job in my named docker volume.
$ ls -l /var/lib/docker/volumes/my-jenkins/_data/jobs/
total 4
drwxr-xr-x 3 dockrema dockrema 4096 Nov 29 14:47 firstjob
Now I will delete my container (id = fa1003894dbc). The container is gone:
$ docker rm -fv fa1003894dbc
I'm a bit later. I want to reuse the named docker volume which still exists to start a new jenkins container which will immediatly container the job "firstjob".
$ docker run -d -p 8080:8080 -v my-jenkins:/var/jenkins_home jenkins
If you have an unnamed docker volume (created automatically with name 0f8018x9cf76b04x163b6xdf) you can use
docker run -d -v 0f8018x9cf76b04x163b6xdf:/var/jenkins_home jenkins
Now your jenkins will use everything which is inside that volume (it's only not a named volume, what makes it more difficult to see with which type of container it was linked. But by accessing the volume folder you will find it in most cases.)

How to get contents generated by a docker container on the local fileystem (minimal failing example)

This question is a minimal failing version of this other one:
How to get contents generated by a docker container on the local fileystem
I have the following files:
./test
-rw-r--r-- 1 miqueladell staff 114 Jan 21 15:24 Dockerfile
-rw-r--r-- 1 miqueladell staff 90 Jan 21 15:23 docker-compose.yml
drwxr-xr-x 3 miqueladell staff 102 Jan 21 15:25 html
./test/html:
-rw-r--r-- 1 miqueladell staff 0 Jan 21 15:22 file_from_local_filesystem
DockerFile
FROM php:7.0.2-apache
RUN touch /var/www/html/file_generated_inside_the_container
VOLUME /var/www/html/
docker-compose.yml
test:
image: test
volumes:
- ./html:/var/www/html/
After running a container built from the image defined in the Dockerfile what I want is having:
./html
-- file_from_local_filesystem
-- file_generated_inside_the_container
Instead of this I get the following:
build the image
$ docker build --no-cache -t test .
Sending build context to Docker daemon 4.096 kB
Step 1 : FROM php:7.0.2-apache
---> 2f16964f48ba
Step 2 : RUN touch /var/www/html/file_generated_inside_the_container
---> Running in b957cc9d7345
---> 5579d3a2d3b2
Removing intermediate container b957cc9d7345
Step 3 : VOLUME /var/www/html/
---> Running in 6722ddba76cc
---> 4408967d2a98
Removing intermediate container 6722ddba76cc
Successfully built 4408967d2a98
run a container with previous image
$ docker-compose up -d
Creating test_test_1
list files on the local machine filesystem
$ ls -al html
total 0
drwxr-xr-x 3 miqueladell staff 102 Jan 21 15:25 .
drwxr-xr-x 5 miqueladell staff 170 Jan 21 14:20 ..
-rw-r--r-- 1 miqueladell staff 0 Jan 21 15:22 file_from_local_filesystem
list files from the container
$ docker exec -i -t test_test_1 ls -alR /var/www/html
/var/www/html:
total 4
drwxr-xr-x 1 1000 staff 102 Jan 21 14:25 .
drwxr-xr-x 4 root root 4096 Jan 7 18:05 ..
-rw-r--r-- 1 1000 staff 0 Jan 21 14:22 file_from_local_filesystem
The volume from the local filesystem gets mounted on the container file system replacing the contents of it.
This is contrary at what I understand in the section "Permissions and Ownership" of this guide Understanding volumes
How could I get the desired output?
Thanks
EDIT: As is said in the accepted answer I did not understand volumes when asking the question. Volumes, as mountponint, replace the container content with the local filesystem that is mounted.
The solution I needed was to use ENTRYPOINT to run the necessary commands to initialize the contents of the mounted volume once the container is running.
The code that originated the question can be seen working here:
https://github.com/MiquelAdell/composed_wordpress/tree/1.0.0
This is from the guide you've pointed to
This won’t happen if you specify a host directory for the volume
Volumes you share from other containers or host filesystem replace directories from container.
If you need to add some files to volume, you should do it after you start container. You can do an entrypoint for example which does touch and then runs your main process.
Yep, pretty sure it should be the full path:
docker-compose.yml
test:
image: test
volumes:
- ./html:/var/www/html/
./html should be /path/to/html
Edit
Output after changing to full path and running test.sh:
$ docker exec -ti dockervolumetest_test_1 bash
root#c0bd7a722b63:/var/www/html# ls -la
total 8
drwxr-xr-x 2 1000 adm 4096 Jan 21 15:19 .
drwxr-xr-x 3 root root 4096 Jan 7 18:05 ..
-rw-r--r-- 1 1000 adm 0 Jan 21 15:19 file_from_local_filesystem
Edit 2
Sorry, I misunderstood the entire premise of the question :)
So you're trying to get file_generated_inside_the_container (which is created inside your docker image only) mounted to some location on your host machine - like a "reverse mount".
This isn't possible to do with any docker commands, but if all you're after is access to your VOLUMEs files on your host, you can find the files in the docker root directory (normally /var/lib/docker). To find the exact location of the files, you can use docker inspect [container_id], or in the latest versions use the docker API.
See cpuguy's answer in this github issue: https://github.com/docker/docker/issues/12853#issuecomment-123953258 for more details.

Resources