Home > other >  Docker: postgres volume location and permissions
Docker: postgres volume location and permissions

Time:11-27

I have the following docker-compose file

version: '3.7'

volumes:
  postgres-data:

services:
 postgres:
    environment:
    - POSTGRES_PASSWORD=mypwd
    - POSTGRES_USER=randomuser
    image: 'postgres:14'
    restart: always
    volumes:
     - './postgres-data:/var/lib/postgresql/data'

I seem to have multiple issues regarding the volume:

  • A folder named postgres-data is created in the docker-compose file location when I run up, though it seems that for other images, they get placed in the /var/lib/docker/volumes folder instead (without creating such a folder). Is this expected ? Is it a good practice to have the volume folder created in the same location as the docker-compose file, instead of the /var/lib/docker/volumes folder ?
  • This folder has weird ownership, I can't get into it as my current user (though I am in the docker group).

I tried reading the image documentation, especially the "Arbitrary --user Notes", but didn't understand what to do with it. I also tried not setting the POSTGRES_USER (which then defaults to postgres), but the result is the same.

What's the correct way to create a volume using this image ?

CodePudding user response:

Your volume mount is explicitly to a subdirectory of the current directory

volumes:
 - './postgres-data:/var/lib/postgresql/data'
#   ^^ (a slash before the colon always means a bind mount)

If you want to use a named volume you need to declare that at the top level of the Compose file, and refer to the volume name (without a slash) when you use it

volumes:
  postgres-data:
services:
  ...
    volumes:
      - 'postgres-data:/var/lib/postgresql/data'
      # ^^ (no slash)

One isn't really "better" than the other for this case. A bind-mounted host directory is much easier to back up; a named volume will be noticeably faster on MacOS or Windows; you can directly see and edit the files with a bind mount; you can use the Docker ecosystem to clean up named volumes. For a database in particular, seeing the data files isn't very useful and I might prefer a named volume, but that's not at all a strong preference.

File ownership for bind mounts is a frequent question. On native Linux, the numeric user ID is the only thing that matters for permission checking. This is resolved by the /etc/passwd file into a username, but the host and container have different copies of this file (and that's okay). The unusual owner you're seeing with ls -l from the host matches the numeric uid of the default user in the postgres image.

That image is well-designed, though, and the upshot of the section in the Docker Hub documentation is that you can specify any Compose user: you want, probably matching the host uid owning the directory.

sudo rm -rf ./postgres-data  # with the wrong owner
id -u                        # what's my current numeric uid?
version: '3.8'
services:
  postgres:
    volumes:    # using a host directory
     - './postgres-data:/var/lib/postgresql/data'
    user: 1000  # matches the `id -u` output
  • Related