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

Viewed 2691

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?

2 Answers

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.

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.

Related