Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permission issue with PostgreSQL in docker container

I'm trying to run a docker image with PostgreSQL that has a volume configured for persisting data.

docker-compose.yml

version: '3.1'

services:
  db:
    image: postgres
    restart: always
    volumes:
      - ./data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: example

When I start the container I see the output

fixing permissions on existing directory /var/lib/postgresql/data ... ok

and the data folder is no longer readable for me.

If I elevate myself and access the data directory I can see that the files are there. Furthermore, the command ls -ld data gives me

drwx------ 19 systemd-coredump root 4096 May 17 16:22 data

I can manually set the directory permission with sudo chmod 755 data, but that only works until I restart the container.

Why does this happen, and how can I fix it?

like image 389
Daniel Avatar asked May 17 '19 14:05

Daniel


People also ask

How do I connect PgAdmin to Docker container?

PgAdmin Docker Setup: Docker Images and Docker Compose. PgAdmin Docker Setup: Creating The Docker Compose File. PgAdmin Docker Setup: Verification of Docker Connection. PgAdmin Docker Setup: Set up the PostgreSQL Connection.


Video Answer


3 Answers

The other answer indeed points to the root cause of the problem, however the help page it points to does not contain a solution. Here is what I came up with to make this work for me:

  1. start the container using your normal docker-compose file, this creates the directory with the hardcoded uid:gid (999:999)
version: '3.7'

services:
  db:
    image: postgres
    container_name: postgres
    volumes:
      - ./data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: fake_database_user
      POSTGRES_PASSWORD: fake_database_PASSWORD
  1. stop the container and manually change the ownership to uid:gid you want (I'll use 1000:1000 for this example
$ docker stop postgres
$ sudo chown -R 1000:1000 ./data 
  1. Edit your docker file to add your desired uid:gid and start it up again using docker-compose (notice the user:)
version: '3.7'

services:
  db:
    image: postgres
    container_name: postgres
    volumes:
      - ./data:/var/lib/postgresql/data
    user: 1000:1000
    environment:
      POSTGRES_USER: fake_database_user
      POSTGRES_PASSWORD: fake_database_password

The reason you can't just use user: from the start is that if the image runs as a different user it fails to create the data files.

On the image documentation page, it does mention a solution to add a volume to expose the /etc/passwd file as read-only in the image when providing --user option, however, that did not work for me with the latest image, as I was getting the following error. In fact none of the three proposed solutions worked for me.

initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
like image 73
Plazgoth Avatar answered Oct 24 '22 10:10

Plazgoth


This is because of what is written in the dockerfile of the postgres image.
From line 15 to 18, you'll see that the group 999 and the user 999 are used. I'm guessing that in your host, they map respectively to systemd-coredump and root.

You need to know that whenever you use a user/group in an image, if the uid/gid exist in your host, then it will be mapped to it.

You can read the documentation on the docker hub from the postgres image here. There is a section Arbitrary --user Notes that explain how it works in the context of this image.

like image 43
Marc ABOUCHACRA Avatar answered Oct 24 '22 09:10

Marc ABOUCHACRA


An easier and permanent solution would be as follows:

Add these lines to ~/.bashrc:

export UID=$(id -u)
export GID=$(id -g)

Reload your shell:

$ source ~/.bashrc

Modify your docker-compose.yml as follows:

version: "3.7"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    user: "${UID}:${GID}"
    ...

Source

like image 32
Erick Avatar answered Oct 24 '22 08:10

Erick