Docker Community Forums

Share and learn in the Docker community.

Trouble understanding named volumes and bind mounts

I am new to Docker. I try to piece together a container that runs Drupal with a Postgres database. I want to have the Drupal and Postgres file be part of my own file system so I experimented with volumes. I found the example from drupal on dockerhub, so I have:

version: '2'  # if no version is specificed then v1 is assumed. 
services: 
  drupal-service:
    image: drupal # Optional if you use build:
    ports: # Optional, same as -p in docker run
      - "8080:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-themes:/var/www/html/themes
      - drupal-sites:/var/www/html/sites
      
  postgres-service:
      image: postgres # Optional if you use build:
      environment: # Optional, same as -e in docker run
        - POSTGRES_PASSWORD=<something>

volumes: 
  drupal-modules:
  drupal-profiles:
  drupal-themes:
  drupal-sites:

This works great. I can create a new site and drupal is up and running in no time. The volumes are created in /var/lib/docker/volumes. The only thing I don’t understand is why I need to add the named volumes in a top level volumes statement.

The disadvantage of named volumes is that the volumes are not placed where I want to have them so I experimented with bind volumes. I tried this setup:

version: '2'  # if no version is specificed then v1 is assumed. 
    services:  
      drupal-service: # a friendly name. 
        image: drupal 
        ports: # same as -p in docker run
          - "8080:80"
        volumes: # same as -v in docker run
          - /home/arnold/development/test/modules:/var/www/html/modules
          - /home/arnold/development/test/profiles:/var/www/html/profiles
          - /home/arnold/development/test/themes:/var/www/html/themes
          - /home/arnold/development/test/sites:/var/www/html/sites
          
      postgres-service:
          image: postgres # Optional if you use build:
          environment: # Optional, same as -e in docker run
            - POSTGRES_PASSWORD=<something>
          volumes:
            - /home/arnold/development/test/pg-data:/var/lib/postgresql/data

All seems to work well when I connect to Drupal until Drupal did a requirements verification. It says that the file system does not exist, the default settings file lacks as does the settings file. I checked the file permissions of /var/lib/docker/volumes and notices they were root. Cleared all mounts, set the owner of /home/arnold/development/test to root. That cleared the error of the file system but not of the settings file.

Why does the named mounts setup have different reaction than the bind mounts setup? What do I miss? And why do I need to add the named volumes in a top level volumes statement?

ubuntu 18.04
docker 18.09.6
docker-compose 1.24