dockerdocker-composedocker-volume

docker-compose named volume copy contents on initial start


I may be a little confused on how volumes work and I keep reading the same things over and over and to me it should be working. I want the contents from a folder inside the container to copy over if the volume gets initialized the first time.


I have something like this:

I have a Dockerfile like this: https://github.com/docker-library/tomcat/blob/f6dc3671bf56465917b52c8df4356fa8f0ebafcd/7/jre7/Dockerfile

And before

EXPOSE 8080
CMD ["catalina.sh", "run"]

I have something like

Tomcat Dockerfile

VOLUME ["/opt/tomcat/conf"]
EXPOSE 8080
CMD ["catalina.sh", "run"]

When i build this image, I tag it as tomcat.


Then I have another Dockerfile with a bunch of environment variables that I set and a script.

Like so:

MyApp Dockerfile

FROM tomcat

ENV SOME_VAR=Test1
COPY assets/script.sh /script.sh

The second image builds from the first image and just adds a script and sets some settings. So far so good.

I want to do something like this in my docker-compose.yml file:


Docker Compose file

website:
  image: myapp
  ports:
    - "8000:8080"
  volumes:
    - /srv/myapp/conf:/opt/tomcat/conf

I want the contents of /opt/tomcat/conf to copy into /srv/myapp/conf when that folder first gets created. Everything I read suggests that this should work, but it just creates the folder and doesn't copy the contents. Am I missing something here?

Basically I have this issue: https://github.com/moby/moby/issues/18670

Oh and my docker-compose yaml file is using version 2.1 if that makes a difference.


Solution

  • What you are looking for is not possible when you are binding host volume inside the container. It will only work if you have a named volume. Then docker will copy the content of the folder to a container. You need to change you compose file to

    version: '3'
    services:
      website:
        image: myapp
        ports:
          - "8000:8080"
        volumes:
          - appconfig:/opt/tomcat/conf
    volumes:
      appconfig: {}
    

    If you want to get the config out then you can use a shell script and your original compose file

    #!/bin/bash
    if [ ! -d "/srv/myapp/conf" ]; then
       mkdir /srv/myapp/conf
       docker create --name myappconfig myapp
       docker cp myapp:/opt/tomcat/conf /srv/myapp/
       docker rm myapp
    fi
    
    docker-compose up -d
    

    For this to work the directory should not exist for the first time.