15

I try to create a docker-compose image for different website.

Everything is working fine except for my volumes.

Here is an exemple of the docker-compose.yml:

version: '2'

services:
  website:
    build: 
        context: ./dockerfiles/                                        
        args:                                                                      
            MYSQL_ROOT_PASSWORD: mysqlp@ssword 
    volumes:
        - ./logs:/var/log
        - ./html:/var/www
        - ./nginx:/etc/nginx
        - ./mysql-data:/var/lib/mysql
    ports:
        - "8082:80"
        - "3307:3306"

Anf here is my Dockerfile:

FROM php:5.6-fpm

ARG MYSQL_ROOT_PASSWORD

RUN export DEBIAN_FRONTEND=noninteractive; \
echo mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD | debconf-set-selections; \
echo mysql-server mysql-server/root_password_again  password $MYSQL_ROOT_PASSWORD | debconf-set-selections;

RUN apt-get update && apt-get install -y -q mysql-server php5-mysql nginx wget

EXPOSE 80 3306

VOLUME ["/var/www", "/etc/nginx", "/var/lib/mysql", "/var/log"]

Everything is working well, expect that all my folders are empty into my host volumes. I want to see the nginx conf and mysql data into my folders.

What am I doing wrong?

EDIT 1 : Actually the problem is that I want docker-compose to create the volume in my docker directory if it not exist, and to use this volume if it exist, as it is explain in https://stackoverflow.com/a/39181484 . But it doesn't seems to work.

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Mayous
  • 2,063
  • 3
  • 13
  • 18
  • I believe this covers your case: [Create Docker volume with preexisting data in it](http://stackoverflow.com/questions/36152081/create-docker-volume-with-preexisting-data-in-it/36152439#36152439) – jrbeverly Feb 22 '17 at 15:40
  • 1
    Possible duplicate of [Create Docker volume with preexisting data in it](http://stackoverflow.com/questions/36152081/create-docker-volume-with-preexisting-data-in-it) – jrbeverly Feb 22 '17 at 15:41
  • 1
    Actually the problem is that I want docker-compose to create the volume in my docker directory if it not exist, and to use this volume if it exist, as it is explain in http://stackoverflow.com/a/39181484. but it doesn't seems to work. – Mayous Feb 22 '17 at 15:50
  • The directory `./logs` is not being created? I thought this way the default behaviour of docker-compose at the moment. – jrbeverly Feb 22 '17 at 15:56
  • Yes it is created but is empty. Should'nt it contains what is already in the containers "/var/log"? – Mayous Feb 22 '17 at 15:57
  • The mounted volumes will not contain the contents of `/var/log`. As covered [here](https://docs.docker.com/engine/tutorials/dockervolumes/), "Volumes are initialized when a container is created. If the container’s base image contains data at the specified mount point, that existing data is copied into the new volume upon volume initialization. (Note that this does not apply when mounting a host directory.)" – jrbeverly Feb 22 '17 at 16:02
  • Ok so it seems that I can't access "/var/log/" If I want to mount a host directory into my container. So how do I access to the "/var/log" content from the container? If I remove volumes from docker-compose, and let the volumes into my dockerfile, I can see that my mount source are visibles into "/var/lib/docker/volumes/.../_data" and contains the files I want. – Mayous Feb 22 '17 at 16:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136376/discussion-between-mayous-and-jrbeverly). – Mayous Feb 22 '17 at 16:15

1 Answers1

27

The problem is that you're expecting files from the Container to be mounted on your host.

This is not the way it works: it's the other way around:

Docker mounts your host folder in the container folder you specify. If you go inside the container, you will see that where there were supposed to be the init files, there will be nothing (or whatever was in your host folder(s)), and you can write a file in the folder and it will show up on your host.

Your best bet to get the init files and modify them for your container is to:

  • Create a container without mounting the folders (original container data will be there)
  • Run the container (the container will have the files in the right place from the installation of nginx etc...) docker run <image>
  • Copy the files out of the container with docker cp <container>:<container_folder>/* <host_folder>
  • Now you have the 'original' files from the container init on your host.
  • Modify the files as needed for the container.
  • Run the container mounting your host folders with the new files in them.

Notes: You might want to go inside the container with shell (docker run -it <image> /bin/sh) and zip up all the folders to make sure you got everything if there are nested folders, then docker cp ... the zip file

Also, be careful about filesystem case sensitivity: on linux files are case sensitive. On Mac OS X, they're not. So if you have Init.conf and init.conf in the same folder, they will collide when you copy them to a Mac OS X host.

MrE
  • 19,584
  • 12
  • 87
  • 105
  • 1
    Thanks for your answer. What I see is that If I mount a volume into the container without specifying anything in docker-compose, the content of each volume is visible in the host into "/var/lib/docker/volumes/.../_data" only if the volume doesn't exist before. What I understand is if I specify another path for my volume into the host (like I did in docker-compose), the behaviour is different, even if the folder doesn't exist before? – Mayous Feb 22 '17 at 16:26
  • You should not have to go mess with the /var/lib/docker/volumes... because that's Docker's internal. Docker will create / delete those folders as needed, so don't rely on that. Docker uses a layered file system, so it re-uses volumes if they are defined multiple times. Again, don't rely on Docker's internal files to do your work: mount the host folder where it belongs on the container and only expect what's in there to show on the container. If you have files in the container folder, they will be there if you do not mount the host folder. – MrE Feb 22 '17 at 16:42
  • if you need both set of files, then you should have an ENTRYPOINT that will run a script and decide which to load. You can then sim-link the right folder/file where need be. – MrE Feb 22 '17 at 16:43
  • This is a great answer, it explains so much about how containers mount on the host. – Sarke Oct 29 '17 at 02:30
  • but why docker mongo works like ~/data/db:/data/db , the container's /data/db will not be empty – leafiy Sep 29 '19 at 18:06
  • If you mount a local (non-empty) directory, yes it will not be empty inside the container. If you first mount it empty and then initialize mongodb, mongo will write its data files in that folder and it will end up in the local folder. – MrE Sep 29 '19 at 18:14