Postgres FATAL: could not open log file permission denied

Rui*_*ian 3 postgresql permissions logging docker

I am deploying postgres in docker and trying to output some logs, however, I am getting an error saying permission denied for the logs file. If I disable logging, everything works. The permission thing only happens when I enable log collection.

Here is a snippet of my docker-compose:

  postgres_db:
    image: postgres:14.1
    restart: unless-stopped
    environment:
      - POSTGRES_USER=${BP_ADMIN_USER}
      - POSTGRES_PASSWORD=${BP_ADMIN_PASSWORD}
    volumes:
      - ./admin/${BP_ENV:-dev}/database:/docker-entrypoint-initdb.d
      - ./admin/${BP_ENV:-dev}/config:/mnt/admin
      - ./data/log_db:/mnt/log
      - ./data/hist_data:/mnt/data
      - ./data/postgres:/var/lib/postgresql/data
    command: postgres -c logging_collector=on -c log_rotation_age=1d -c log_directory=/mnt/log -c log_destination='stderr' -c log_filename='postgresql-%Y-%m-%d_%H%M%S.log'
    ports:
      - "5432:5432"
Run Code Online (Sandbox Code Playgroud)

The error is as follows:

UTC [1] FATAL:  could not open log file "/mnt/log/postgresql-2022-01-10_224118.log": Permission denied
Run Code Online (Sandbox Code Playgroud)

I am running this on a Linux Ubuntu 20-04 VM. I saw some answers where they changed the permissions of the host directory. That is something I did not want to do. I also saw some old 2016 answers of work arounds. But I was wondering if there is a more elegant solution available now.

Note: I did not get this error until this morning. For whatever reason, it was working last week.

Han*_*ian 5

Postgres runs under a user called 'postgres' with UID 999 inside the container. When that user accesses files you have bind mounted from the host, the container UID needs to have access to those files on the host.

You get an error because UID 999 doesn't have access to ./data/log_db/postgresql-2022-01-10_224118.log on your host machine.

To allow the docker user to create files in the directory, you can change the group owner of the directory to group 999 (which is the group id of the postgres user in the container). Set the directory to be fully accessible by owner and group members. Then set the setgid bit on the directory so all files in the directory will inherit the group ownership.

chown :999 ./data/log_db
chmod 770 ./data/log_db
chmod g+s ./data/log_db
Run Code Online (Sandbox Code Playgroud)

Now you should be able to run your container. You'll see that the log files created are owned by user '999' and are only accessible by that user (and root).