5

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?

madx
  • 6,723
  • 4
  • 55
  • 59

2 Answers2

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.

acran
  • 7,070
  • 1
  • 18
  • 35
  • 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? – madx Mar 22 '21 at 11:11
  • 1
    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) – acran Mar 22 '21 at 15:44
  • 1
    You could also bend the `local` volume driver to use a specific path on the host, [see this e.g. answer](https://stackoverflow.com/a/49920624/11932806). 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. – acran Mar 22 '21 at 15:55
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.

BertC
  • 2,243
  • 26
  • 33