skip to Main Content

I’m looking to use docker-compose to create a volume that contains existing files from one container and allow them to be shared with another. I’ve tried this with named volumes and the share works, but it deletes the existing files when the volume is created.

I’ve seen examples that use Dockerfile to copy the files after the volume is created, but is there another way to just share files without overwriting them?

2

Answers


  1. Have you checked that documentation? https://ellis.codes/blog/using-docker-volume-mounts-without-overwriting-the-image-contents

    version: "3.7"
    
    services:
      test:
        image: alpine
        command: "cat /greeting/welcome.txt"
        volumes:
          - public:/greeting
      app:
        build:
          context: . # ensure the Dockerfile is present in the same directory
        restart: unless-stopped
        volumes:
          - public:/app/public
    volumes:
      public:
    

    This will create a named volume called public and copy the files from /app/public in the app container to it. Then, the nginx container will mount the same volume to /usr/share/nginx/html and serve those files.

    Login or Signup to reply.
  2. Docker does not have a way to share files from one image to another container.

    Docker named volumes often get cited as an approach for this. Volume mounts act like every other Unix mount, though: if there is already content in the named volume, the content of the named volume hides whatever was in the target directory, in both the "source" and "destination" containers. Volume mounts only act on entire directories and not individual files, which doesn’t seem to match your use case. If the "source" image gets updated, you’ll also see the behavior you describe, where the old content in the volume hides the content at both mount points, and your changes won’t be seen.

    I’d suggest two potential approaches here.

    The first is to COPY the files you need into all of the images that need them. An Nginx reverse proxy that directly serves static assets frequently needs this pattern, and you can write a simple Dockerfile

    FROM nginx:1.23
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY static/ /usr/share/nginx/html/static/
    

    You can directly docker run this image without mounting or sharing anything.

    For things like dynamic uploads, you can use a named volume or other storage to share files between two containers. I would not rely on the behavior of Docker automatically copying files from the image into a volume: it only works on Docker and not other environments like Kubernetes, and it has the problems described above of ignoring updates in the image. Instead, mount the volume on an empty directory in both containers. If your application needs some data there, seed it in an entrypoint wrapper script

    #!/bin/sh
    # This file is entrypoint.sh.
    # In your Dockerfile declare
    # ENTRYPOINT ["./entrypoint.sh"]
    
    # If we don't have the seed content in the data storage, copy if in.
    if [ ! -f /data/seed.txt ]; then
      cp -r /app/data /data
    fi
    
    # Run whatever was given to us as the main container command.
    exec "$@"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search