Postgres mounting volume in docker. Permission denied

12,034

Solution 1

The following works for me, perhaps you need to start with a simpler set up that works and find out what causes a problem as you move towards your complete config:

version: '3.7'

volumes:
   pg-data:

services:
  database:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      PGDATA: /pg-data
    ports:
      - "5432:5432"
    volumes:
      - pg-data:/pg-data

So ...

########################################
# start db
########################################
▶ docker-compose up -d
Creating docker-compose-pg_database_1 ... done

########################################
# note pg-data is created
########################################
▶ ls
docker-compose.yml pg-data

########################################
# create some data
########################################
▶ docker-compose exec database psql -U postgres
psql (12.2 (Debian 12.2-2.pgdg100+1))
Type "help" for help.

postgres=# create database foo;
CREATE DATABASE
postgres=# \q

########################################
# remove the container and any non-mounted data
########################################
▶ docker-compose rm -sf
Stopping docker-compose-pg_database_1 ... done
Going to remove docker-compose-pg_database_1
Removing docker-compose-pg_database_1 ... done

########################################
# start the container again
########################################
▶ docker-compose up -d
Creating docker-compose-pg_database_1 ... done

########################################
# see data from before
########################################
▶ docker-compose exec database psql -U postgres
psql (12.2 (Debian 12.2-2.pgdg100+1))
Type "help" for help.

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 foo       | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(4 rows)

Solution 2

This is what have worked for me on manjaro linux.

First I need to manually create pgdata folder. If I omit this step, docker will create pgdata with the wrong permission.

mkdir -p /some/path/pddata

Next I create the docker container and map my user with the --user argument:

docker container run -d --name=pg -p 5432:5432 --user $(id -u):$(id -g) -e POSTGRES_PASSWORD=postgres -e PGDATA=/pgdata -v /host/path/to/pgdata:/pgdata postgres:latest
Share:
12,034
Viktor
Author by

Viktor

PHP 6+ years, Golang 1+ year, JavaScript 3+ years (native, vue, react). Highly familiar with a big number of web programming tools. Diploma in Computer Science

Updated on June 09, 2022

Comments

  • Viktor
    Viktor almost 2 years

    I try to mapping folder on the host to postgres container in order to save my data even if container destroy.

    Firstly I created new directory pg-data

    enter image description here

    Secondly I describe container in docker-compose.yml

    version: '3.7'
    
    networks:
      backend-network:
        driver: bridge
      frontend-network:
        driver: bridge
    
    volumes:
       redis-data:
       pg-data:
    
    services:
      &app-service app: &app-service-template
        container_name: k4fntr_app
        build:
          context: ./docker/php-fpm
          args:
            UID: ${UID?Use your user ID}
            GID: ${GID?Use your group ID}
            USER: ${USER?Use your user name}
        user: "${UID}:${GID}"
        hostname: *app-service
        volumes:
          - /etc/passwd/:/etc/passwd:ro
          - /etc/group/:/etc/group:ro
          - ./:/var/www/k4fntr
        environment:
          APP_ENV: "${APP_ENV}"
          CONTAINER_ROLE: app
          FPM_PORT: &php-fpm-port 9000
          FPM_USER: "${UID:-1000}"
          FPM_GROUP: "${GID:-1000}"
        depends_on:
          - redis
          - database
        networks:
          - backend-network
    
      &queue-service queue:
        <<: *app-service-template
        container_name: k4fntr_queue
        restart: always
        hostname: *queue-service
        depends_on:
          - app
        environment:
          CONTAINER_ROLE: queue
    
      &schedule-service schedule:
        <<: *app-service-template
        container_name: k4fntr_schedule
        restart: always
        hostname: *schedule-service
        depends_on:
          - app
        environment:
          CONTAINER_ROLE: scheduler
    
      &php-fpm-service php-fpm:
        <<: *app-service-template
        container_name: k4fntr_php-fpm
        user: 'root:root'
        restart: always
        hostname: *php-fpm-service
        ports: [*php-fpm-port]
        entrypoint: /fpm-entrypoint.sh
        command: php-fpm --nodaemonize -d "opcache.enable=0" -d "display_startup_errors=On" -d "display_errors=On" -d "error_reporting=E_ALL"
        networks:
          - backend-network
          - frontend-network
    
      mail:
        container_name: k4fntr_mail
        image: mailhog/mailhog
        ports:
        - "1025:1025"
        - "8025:8025"
          - backend-network
    
      database:
        container_name: k4fntr_database
        build: ./docker/postgres
        restart: always
        environment:
          ENV: ${APP_ENV}
          TESTING_DB: ${DB_DATABASE_TESTING}
          POSTGRES_DB: ${DB_DATABASE}
          POSTGRES_USER: ${DB_USERNAME}
          POSTGRES_PASSWORD: ${DB_PASSWORD}
        ports:
          - "15432:5432"
        volumes:
          - ./docker/postgres/prod/:/prod
          - ./docker/postgres/pg-data:/var/lib/postgresql/data:Z
        networks:
          - backend-network
    
        - backend-network
    
      database:
        container_name: k4fntr_database
        build: ./docker/postgres
        restart: always
        environment:
          ENV: ${APP_ENV}
          TESTING_DB: ${DB_DATABASE_TESTING}
          POSTGRES_DB: ${DB_DATABASE}
          POSTGRES_USER: ${DB_USERNAME}
          POSTGRES_PASSWORD: ${DB_PASSWORD}
        ports:
          - "15432:5432"
        volumes:
          - ./docker/postgres/prod/:/prod
          - ./docker/postgres/pg-data:/var/lib/postgresql/data:rw
        networks:
          - backend-network
    
        - backend-network
    
      nginx:
        container_name: k4fntr_nginx
        image: nginx
        volumes:
        - ./docker/nginx/config:/etc/nginx/conf.d
        - ./:/var/www/k4fntr
        depends_on:
          - *php-fpm-service
        ports:
          - "8084:80"
        networks:
          - frontend-network
    
      redis:
        container_name: k4fntr_redis
        image: redis
        restart: always
        command: redis-server
        volumes:
          - ./docker/redis/config/redis.conf:/usr/local/etc/redis/redis.conf
          - ./docker/redis/redis-data:/data:rw
        ports:
         - "16379:6379"
        networks:
          - backend-network
    
      database:
        container_name: k4fntr_database
        build: ./docker/postgres
        restart: always
        environment:
          ENV: ${APP_ENV}
          TESTING_DB: ${DB_DATABASE_TESTING}
          POSTGRES_DB: ${DB_DATABASE}
          POSTGRES_USER: ${DB_USERNAME}
          POSTGRES_PASSWORD: ${DB_PASSWORD}
        ports:
          - "15432:5432"
        volumes:
          - ./docker/postgres/prod/:/prod
          - ./docker/postgres/pg-data:/var/lib/postgresql/data:Z
        networks:
          - backend-network
    

    I also have Dockerfile in docker/postgres/ which is contains the next code

        FROM postgres:10.5-alpine
    
        COPY /docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
    
        RUN apk add openssh-client
        RUN chmod a+r /docker-entrypoint-initdb.d/*
    
        RUN mkdir /prod
    
        RUN chmod a+r /prod
    

    Then I build my image with docker-compose exec -d --build

    After it my user changes on 70:root

    enter image description here

    and I can't doing any with this folder without sudo. Also when I try to rebuild the container I got an error

    /usr/local/bin/docker-compose up -d --build
    Building database
    Traceback (most recent call last):
      File "bin/docker-compose", line 6, in <module>
      File "compose/cli/main.py", line 72, in main
      File "compose/cli/main.py", line 128, in perform_command
      File "compose/cli/main.py", line 1077, in up
      File "compose/cli/main.py", line 1073, in up
      File "compose/project.py", line 548, in up
      File "compose/service.py", line 351, in ensure_image_exists
      File "compose/service.py", line 1106, in build
      File "site-packages/docker/api/build.py", line 160, in build
      File "site-packages/docker/utils/build.py", line 30, in tar
      File "site-packages/docker/utils/build.py", line 49, in exclude_paths
      File "site-packages/docker/utils/build.py", line 214, in rec_walk
      File "site-packages/docker/utils/build.py", line 184, in rec_walk
    PermissionError: [Errno 13] Permission denied: '/home/ubuntu/PhpstormProjects/fntr/docker/postgres/pg-data'
    [16332] Failed to execute script docker-compose
    

    And I need to remove this folder (with sudo) and then do rebuild.

    What I tried:

    1 - I have read the instruction from https://hub.docker.com/_/postgres (Arbitrary --user Notes) and tried to volume /etc/passwd inside the container and user: "${UID}:${GID}", but got an error

    initdb: could not access directory "/var/lib/postgresql/data": permission denied
    

    2 - use PGDATA into another place and got the same error with rebuild

    3 - create /var/lib/postgresql/data in Dockerfile with 777 permissions, but postgres entrypoints from image just removed this folder and recreated it

    I really need help with this issue because I spent 3 days without effect