简体   繁体   中英

How to map a docker containers directory to the host with docker-compose?

Given following docker-compose.yml setup:

version: '3.7'

services:
  reverse:
    container_name: nginx-reverse-proxy
    hostname: nginx-reverse-proxy
    image: nginx:stable
    ports:
      - 80:80
      - 433:433
    volumes:
      - type: bind
        source: ./config
        target: /etc/nginx
        consistency: consistent

this results in ./config folder being mapped to the container nginx-reverse-proxy and therefore in an empty /etc/nginx directory inside the container.

Goal :
Mapping a folder from container to host. In my example from container /etc/nginx to the host ./config .

My current search constantly results in mapping a directoy from host to container (which i do not want).

Any hints/solutions are appreciated. Thanks!

My current solution is ugly: I created the container with docker and copied the files from /etc/nginx to ./config . Removing the container and using the docker-compose up works and nginx starts because the needed files are already on the host.

Edit: The folder is not present at creation. Docker compose is creating the folder as stated in the docs.

Reading from: Dockers Volume Page

Volumes have several advantages over bind mounts:

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


So a simple docker-compose (inside a folder called nginx):

version: "3.7"
volumes:
  xmpl:

services:
  testnginx:
    image: nginx:stable
    volumes:
      - xmpl:/etc/nginx

Will yield all the files on the host system via:

$ docker-compose up
$ docker inspect nginx_xmpl
...
"Mountpoint": "/var/lib/docker/volumes/nginx_xmpl/_data"

And you can then view the files on the host :

# ls /var/lib/docker/volumes/nginx_xmpl/_data                               
  conf.d       fastcgi_params koi-utf    koi-win  
  mime.types   modules        nginx.conf scgi_params    
  uwsgi_params win-utf

And finally to use it from ./config :

# ln -s /var/lib/docker/volumes/nginx_xmpl/_data ./config
# ls config
  conf.d       fastcgi_params koi-utf    koi-win  
  mime.types   modules        nginx.conf scgi_params    
  uwsgi_params win-utf

Generally, it is not possible since containers are just "runnable images" and stored like a batch of zip files in the fs. On run event, they are flattened to a "folder" where Linux core does a chroot and starts processes using this root.

OPTIONALLY you can at the end of the process map some paths from the host OS to some paths in the chrooted folder , but not the way back. When Docker makes the mapping, it replaces path completely, so all the existing files in the path will "hidden" from the image fs and "replaced" by the mapped host path.

I think you want to take a look at "default files configuration" for a path in an image. There are two ways from my point of view:

  • Start a container with mapped path to another directory and when your container starts just copy the required folder contents using the container shell to the mapped folder. Example: let's map /export to the host's ./exported-configs and when container starts go into the running container using docker exec {.... extra params and docker ps id} bash and run something like cp -R /etc/nginx /export/nginx-configs .
  • export the whole image filesystem using https://docs.docker.com/engine/reference/commandline/export/ and take a look at the interesting image configuration and so it.

Both ways are working, usually, I do the first one if I need any folders from the image.

Good luck!

Well, you shouldn't do the mapping the way you do it, cause as you said it's ugly. The most convenient and hassle-free way to do it is like so:

version: '3.7'

    services:
      reverse:
        container_name: nginx-reverse-proxy
        hostname: nginx-reverse-proxy
        image: nginx:stable
        ports:
          - 80:80
          - 433:433
        volumes:
          - ./nginx-conf/myapp/nginx.conf:/etc/nginx/nginx.conf
          - ./nginx-conf/myapp/sites-enabled:/etc/nginx/sites-enabled


    volumes:
      nginx-conf:
    networks:
      myapp-net:
        driver: bridge

The location /etc/nginx contains also other files, (mime.types and fastcgi_params for instance) which will not exist if you map the host directory ./config , unless of course, you copy them to the host instead, but that's not a pretty solution.

Above, i just mapped a local nginx.conf file, located in /nginx/myapp folder to /etx/nginx/nginx.conf and a local sites-enabled folder to /etc/nginx/sites-enabled folder in the container.

You would be better off by keeping things as simple as possible because docker is already complicated by nature.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM