Docker compose volume: copying folder from docker container to host when executing docker-compose up
Asked Answered
T

2

6

I have this simple docker-compose.yaml (image from danielemaddaluno/self-service-password):

version: "3"
services:
  ltb:
      image: danielemaddaluno/self-service-password
      ports:
        - 8080:80
      volumes:
        - ./conf:/var/www/html/conf/

The current behaviour is that:

  • if the ./conf doesn't exist, it is created on the host
  • and the empty content is mounted in the container at /var/www/html/conf/

The behaviour that I wanted it's that:

  • if the ./conf doesn't exist, it is created on the host
  • and the content is firstly loaded from container's /var/www/html/conf/ (to the newly created ./conf host's folder)

Is this possible with docker compose?

Troll answered 20/3, 2021 at 17:6 Comment(0)
T
4

This is possible but only with volume mounts: docker and thus docker-compose distinguishes between (named) volumes and bind mounts, most notably:

  • New volumes can have their content pre-populated by a container.

With bind mounts you specify an absolute path to a directory or file on the docker host to be bind-mounted into the container.

Technically volumes do the same with the difference that the source directory/file on the host is completely managed by docker, i.e. you can create/list/delete them with the docker volume command. This allows docker to provide additional features for those volumes, e.g. to populate the volume with the contents of the container image at the target directory in the image when the volume is first created.

In contrast using a bind mount will always override/hide the contents of the target path.

To use a named volume use this docker-compose.yml

version: "3"
services:
  ltb:
      image: danielemaddaluno/self-service-password
      ports:
        - 8080:80
      volumes:
        - conf:/var/www/html/conf/

volumes:
  conf:

This will automatically create a new named volume conf and populate it with the contents of /var/www/html/conf/ of the danielemaddaluno/self-service-password when you first start it - i.e. subsequent runs will reuse the existing volume and not copy the contents again!


If using a volume is not feasible for you but you must use a bind mount you'll have to manage the initialization/population of the volume yourself, e.g. by using an entrypoint script to copy files from the container into an empty volume.

Torpid answered 21/3, 2021 at 16:17 Comment(3)
First of all thank you for your answer. That seems exactly what I needed. I'm a little bit new on docker, I tried launching a docker-compose up on your suggested docker-compose.yml (the one with volumes: conf:) but no folder it's created... Am I missing something? Where is the new named volume conf located? Can I locate it in the same folder of the yaml as I did with my yaml?Troll
Well, that's exactly the drawback: when using a named volume the underlying source directory (or file) is completely managed by docker and is not placed in your project directory but somewhere else, e.g. under /var/lib/docker, depending on the used volume driver. If you really need to access the volume directly on the host / need to place it at a specific path - and chances are you actually don't - use a bind mount with some custom initialisation (e.g. using an entrypoint script, initiailisation service)Torpid
You could also bend the local volume driver to use a specific path on the host, see this e.g. answer. But I would really not recommend this, especially for a beginner! Instead try to get familiar with named volumes and how to use them correctly.Torpid
N
0

My guess is that this is not possible. The reason is that docker-compose maps the folder in the container to the host folder and overwrites what was originally in the image.

If you want to have the default conf file on your host, a better way is to first leave out the volumes mapping, then exec into the container, copy that conf file and create it on the host conf-folder.

From then on the conf file is available.

Also, you map './conf' (without trailing slash) to a folder (with trailing slash) in the container. Don't know if this works and I would keep the trialing slash in sync between host and container in the volume definition.

Nickens answered 21/3, 2021 at 0:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.