2

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)

Community
  • 1
  • 1
Miquel Adell
  • 1,132
  • 3
  • 11
  • 24
  • Does [this other question](http://stackoverflow.com/questions/30040708/how-to-mount-local-volumes-in-docker-machine?rq=1) helps ? – Maen Jan 21 '16 at 12:39
  • I think it doesn't. It does offer a solution to "getting the files there" but I'm building a base for web development so I really need to have the files shared between local and container filesystem. Thanks! – Miquel Adell Jan 21 '16 at 12:49

3 Answers3

0

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
Chris McKinnel
  • 14,694
  • 6
  • 64
  • 67
  • Yes, you were right about my misunderstanding. Isn't there a way to get the -v functionality in a docker-compose declaration? I'm trying to build a self building environment on tutum and it relies on them. Thanks a lot for the answer – Miquel Adell Jan 21 '16 at 14:57
  • Sorry just been fact checking myself - I think your problem is you don't have the full path in your `docker-compose.yml` file on both sides of the `:`. I'll update my answer. – Chris McKinnel Jan 21 '16 at 14:58
0

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.

Community
  • 1
  • 1
Miquel Adell
  • 1,132
  • 3
  • 11
  • 24
0

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
tgallacher
  • 1,594
  • 1
  • 10
  • 7