问题
EDIT: I'm not longer using docker so I'll not be able to test answers to this question
thanks to all for the suggestions!
TL;DR: can you point me to a simple example of an image that writes changes to a volume shared between the container and the host filesystem?
Hi,
I have some trouble understanding how volumes work.
I've read the Dockerfile reference and also understanding volumes
What I'm trying to do
- I have an image that makes a composer installation of wordpress on RUN to /var/tmp/html
- then ONBUILD I use some information from docker-compose.yml ENVIRONMENT variables to make some more operations to /var/tmp/html
- As the last step I want everything to be copied to /var/www/html and have it acessessible from the composer (be able to run apache pointing to those files) and from the local filesystem (I will code things to this html directory)
What I have right now
Test 1
Dockerfile
docker-compose.yml
The link above is a link to the specific version on github of those files
This test is just everything to install wordpress without any volume information
Result
Bashing into the image and listing /var/www/html
I get:
root@4484ccdb63ca:/var/www/html# ls -al
total 32
drwxr-xr-x 6 www-data www-data 4096 Jan 21 11:45 .
drwxr-xr-x 6 root root 4096 Jan 21 11:45 ..
-rw-r--r-- 1 www-data www-data 10 Jan 21 10:47 .gitignore
-rw-r--r-- 1 www-data www-data 138 Jan 21 10:47 composer.json
-rw-r--r-- 1 www-data www-data 3718 Jan 21 10:47 composer.lock
-rw-r--r-- 1 www-data www-data 428 Jan 21 10:47 index.php
drwxr-xr-x 6 www-data www-data 4096 Jan 21 11:45 vendor
drwxr-xr-x 8 www-data www-data 4096 Jan 21 11:45 wordpress
wich is ok
and listing ./html on the local filesystem I get
total 0
drwxr-xr-x 3 miqueladell staff 102 Jan 21 10:33 .
drwxr-xr-x 11 miqueladell staff 374 Jan 21 13:04 ..
-rw-r--r-- 1 miqueladell staff 0 Jan 21 10:33 foo
which is wrong but totally expected. The files are ok on the container but have nothing to do outside the container because I did not provide any volume information.
Test 2
Dockerfile
docker-compose.yml
The link above is a link to the specific version on github of those files
adds VOLUME on Dockerfile and docker-compose.yml
this is a paste of the diff
Dockerfile
- # VOLUME /var/www/html/
+ VOLUME /var/www/html/
docker-compose.yml
- # volumes:
- # - .html:/var/www/html/
+ volumes:
+ - ./html:/var/www/html/
The result of building the image and running the cointainer is both empty an empty html directory on the container and no change to the local filesystem
Thanks!
EDIT: I've created a minimal failing version of this question: How to get contents generated by a docker container on the local fileystem (minimal failing example)
回答1:
I think you have a small misunderstanding of what VOLUME in your Dockerfile does and what -v does when you run a docker container.
The fundamental difference between VOLUME and -v is this: -v will mount existing files from your operating system inside your docker container and VOLUME will create a new, empty volume on your host (stored in /var/lib/docker/xxxxx) and mount it inside your container.
Example:
We have a file test-file in /home/test/
cmckinnel at arch in /home/test
$ ll
total 8
drwxr-xr-x 2 cmckinnel adm 4096 Jan 21 14:40 .
drwxr-xr-x 4 root root 4096 Jan 21 14:40 ..
-rw-r--r-- 1 cmckinnel adm 0 Jan 21 14:40 test-file
We want to mount this directory inside our docker container so when we change a file on our host, it changes inside the container.
This is what you're currently doing (creating an empty VOLUME inside your container at /home/test):
Dockerfile
FROM ubuntu:14.04
VOLUME /home/test
Build this image and run a container from it:
$ docker build -t test-creating-volume .
$ docker run -ti test-creating-volume bash
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 14:41 ./
drwxr-xr-x 3 root root 4096 Jan 21 14:41 ../
What you actually want to do instead is use -v when you docker run:
Dockerfile
FROM ubuntu:14.04
Build this image and run a container from it:
$ docker build -t test-mounting-volume .
$ docker run -ti -v /home/test:/home/test test-mounting-volume bash
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 1000 adm 4096 Jan 21 14:40 ./
drwxr-xr-x 3 root root 4096 Jan 21 14:51 ../
-rw-r--r-- 1 1000 adm 0 Jan 21 14:40 test-file
Edit
Oops, I think your actual problem above is you don't have the full path in your volume: declaration in your docker-compose.yml file.
Example:
docker-compose.yml (note .home doesn't exist)
test-mounting-volume:
image: test-mounting-volume:
volumes:
- .home:/home/test
Then:
$ docker-compose run test-mounting-volume
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 15:01 ./
drwxr-xr-x 3 root root 4096 Jan 21 15:01 ../
But if you put the full path:
docker-compose.yml:
test-mounting-volume:
image: test-mounting-volume:
volumes:
- /home/test:/home/test
Then:
$ docker-compose run test-mounting-volume
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 15:01 ./
drwxr-xr-x 3 root root 4096 Jan 21 15:01 ../
-rw-r--r-- 1 1000 adm 0 Jan 21 14:40 test-file
回答2:
Volumes function like mountpoints so when a volume is mounted the contents of the mount point are the ones that get to the container.
As answered in this (simplified) question the solution is to do the operations on an entrypoint that will get executed after the volume is mounted.
回答3:
Looking over version 2 of your Dockerfile and docker-compose.yml file I suggest the following edits:
Dockerfile
Around Line 70: change from
WORKDIR /tmp/html
ONBUILD RUN rsync --ignore-existing -a /tmp/html/ .
to
WORKDIR /var/www/html
ONBUILD RUN rsync --ignore-existing -a /tmp/html/ .
WORKDIR sets the default path for scripts being run (and when you log into the container).
In your first example you are effectively copying the contents of /tmp/html to itself with rsync, and then later you bin that directory. Plus this directory isn't exposed outside the container.
With the above change, you will copy the contents of /tmp/html to the /var/www/html, which is then exposed outside the container, and later mapped to your local machine using the docker-compose file.
Docker-compose.yml
Try the following file:
wordpress:
image: miqueladell/composed_wordpress_test
links:
- wordpress_db:mysql
environment:
- VIRTUAL_HOST=miqueladell.dev
- WORDPRESS_DB_NAME=wordpress
ports:
- "80:80"
volumes:
- ./html:/var/www/html
wordpress_db:
image: miqueladell/mariadb-utf8mb4
environment:
- MYSQL_ROOT_PASSWORD=password
来源:https://stackoverflow.com/questions/34924011/how-to-get-contents-generated-by-a-docker-container-on-the-local-fileystem