Docker Compose - Share named volume between multiple containers

I'm using docker-compose and v3. I'm trying to mount a volume in docker:

./appdata:/appdata

I'd like to have this as a volume and then reference that volume from multiple containers. The volume configuration reference only shows data-volume: as a named volume, with no value, so it doesn't look like the above.

services:

    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume

volumes:
     app-volume: ./appdata:/appdata

This gives me:

ERROR: In file './docker-compose.yml', volume 'app-volume' must be a mapping not a string.

Obviously I know I need to change the volumes key/value pair, but I'm not sure how to change this so I can share a volume between services.

I've also checked out volumes_from but this effectively just allows inheritance from other containers. I've seen someone use volumes_from on another container that contains the mapping they want, but with command: true set so that the container is never actually run, which to me just seems like a hack.

How can I do this?


Note, I do have the following working:

nginx:
    volumes:
        - ./appdata:/appdata
php:
    volumes:
        - ./appdata:/appdata

But that's just duplication and is something I'm hoping a named volume could help me avoid :-)


Solution 1:

The named volumes can be shared across containers in the following way:

services:
    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume:location_in_the_container

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume:location_in_the_container

volumes:
     app-volume: 

Here's an example config that I use for better understanding. I'm exposing the static files generated from my web container to a named volume called static-content which is then read and served by the nginx container:

services:
  nginx:
    container_name: nginx
    build: ./nginx/

    volumes:
      - static-content:/usr/src/app

  web:
    container_name: web
    env_file: .env
    volumes:
      - static-content:/usr/src/app/public
    environment:
      - NODE_ENV=production

    command: npm run package

volumes:
  static-content:

Solution 2:

This solves it without using named volumes:

      volumes:
          - ./appdata:/appdata

So, it looks like:

services:

  nginx:
      build: ./nginx/
      ports:
          - 80:80
      links:
          - php
      volumes:
          - ./appdata:/appdata

  php:
      build: ./php/
      expose:
          - 9000
      volumes:
          - ./appdata:/appdata