How to customize the configuration file of the official PostgreSQL Docker image?

后端 未结 11 1981
时光取名叫无心
时光取名叫无心 2020-11-29 16:11

I\'m using the official Postgres Docker image trying to customize its configuration. For this purpose, I use the command sed to change max_connections

相关标签:
11条回答
  • 2020-11-29 16:24

    With Docker Compose

    When working with Docker Compose, you can use command: postgres -c option=value in your docker-compose.yml to configure Postgres.

    For example, this makes Postgres log to a file:

    command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs
    

    Adapting Vojtech Vitek's answer, you can use

    command: postgres -c config_file=/etc/postgresql.conf
    

    to change the config file Postgres will use. You'd mount your custom config file with a volume:

    volumes:
       - ./customPostgresql.conf:/etc/postgresql.conf
    

    Here's the docker-compose.yml of my application, showing how to configure Postgres:

    # Start the app using docker-compose pull && docker-compose up to make sure you have the latest image
    version: '2.1'
    services:
      myApp:
        image: registry.gitlab.com/bullbytes/myApp:latest
        networks:
          - myApp-network
      db:
         image: postgres:9.6.1
         # Make Postgres log to a file.
         # More on logging with Postgres: https://www.postgresql.org/docs/current/static/runtime-config-logging.html
         command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs
         environment:
           # Provide the password via an environment variable. If the variable is unset or empty, use a default password
           - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-4WXUms893U6j4GE&Hvk3S*hqcqebFgo!vZi}
         # If on a non-Linux OS, make sure you share the drive used here. Go to Docker's settings -> Shared Drives
         volumes:
           # Persist the data between container invocations
           - postgresVolume:/var/lib/postgresql/data
           - ./logs:/logs
         networks:
           myApp-network:
             # Our application can communicate with the database using this hostname
             aliases:
               - postgresForMyApp
    networks:
      myApp-network:
        driver: bridge
    # Creates a named volume to persist our data. When on a non-Linux OS, the volume's data will be in the Docker VM
    # (e.g., MobyLinuxVM) in /var/lib/docker/volumes/
    volumes:
      postgresVolume:
    

    Permission to write to the log directory

    Note that when on Linux, the log directory on the host must have the right permissions. Otherwise you'll get the slightly misleading error

    FATAL: could not open log file "/logs/postgresql-2017-02-04_115222.log": Permission denied

    I say misleading, since the error message suggests that the directory in the container has the wrong permission, when in reality the directory on the host doesn't permit writing.

    To fix this, I set the correct permissions on the host using

    chgroup ./logs docker && chmod 770 ./logs
    
    0 讨论(0)
  • 2020-11-29 16:25

    This works for me:

    FROM postgres:9.6
    USER postgres
    
    # Copy postgres config file into container
    COPY postgresql.conf /etc/postgresql
    
    # Override default postgres config file
    CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
    
    0 讨论(0)
  • 2020-11-29 16:27

    You can put your custom postgresql.conf in a temporary file inside the container, and overwrite the default configuration at runtime.

    To do that :

    • Copy your custom postgresql.conf inside your container
    • Copy the updateConfig.sh file in /docker-entrypoint-initdb.d/

    Dockerfile

    FROM postgres:9.6
    
    COPY postgresql.conf      /tmp/postgresql.conf
    COPY updateConfig.sh      /docker-entrypoint-initdb.d/_updateConfig.sh
    

    updateConfig.sh

    #!/usr/bin/env bash
    
    cat /tmp/postgresql.conf > /var/lib/postgresql/data/postgresql.conf
    

    At runtime, the container will execute the script inside /docker-entrypoint-initdb.d/ and overwrite the default configuration with yout custom one.

    0 讨论(0)
  • 2020-11-29 16:30

    Inject custom postgresql.conf into postgres Docker container

    The default postgresql.conf file lives within the PGDATA dir (/var/lib/postgresql/data), which makes things more complicated especially when running postgres container for the first time, since the docker-entrypoint.sh wrapper invokes the initdb step for PGDATA dir initialization.

    To customize PostgreSQL configuration in Docker consistently, I suggest using config_file postgres option together with Docker volumes like this:

    Production database (PGDATA dir as Persistent Volume)

    docker run -d \
    -v $CUSTOM_CONFIG:/etc/postgresql.conf \
    -v $CUSTOM_DATADIR:/var/lib/postgresql/data \
    -e POSTGRES_USER=postgres \
    -p 5432:5432 \
    --name postgres \
    postgres:9.6 postgres -c config_file=/etc/postgresql.conf
    

    Testing database (PGDATA dir will be discarded after docker rm)

    docker run -d \
    -v $CUSTOM_CONFIG:/etc/postgresql.conf \
    -e POSTGRES_USER=postgres \
    --name postgres \
    postgres:9.6 postgres -c config_file=/etc/postgresql.conf
    

    Debugging

    1. Remove the -d (detach option) from docker run command to see the server logs directly.
    2. Connect to the postgres server with psql client and query the configuration:

      docker run -it --rm --link postgres:postgres postgres:9.6 sh -c 'exec psql -h $POSTGRES_PORT_5432_TCP_ADDR -p $POSTGRES_PORT_5432_TCP_PORT -U postgres'
      
      psql (9.6.0)
      Type "help" for help.
      
      postgres=# SHOW all;
      
    0 讨论(0)
  • 2020-11-29 16:33

    A fairly low-tech solution to this problem seems to be to declare the service (I'm using swarm on AWS and a yaml file) with your database files mounted to a persisted volume (here AWS EFS as denoted by the cloudstor:aws driver specification).

      version: '3.3'
      services:
        database:
          image: postgres:latest
          volumes:
            - postgresql:/var/lib/postgresql
            - postgresql_data:/var/lib/postgresql/data
        volumes:
           postgresql:
             driver: "cloudstor:aws" 
           postgresql_data:
             driver: "cloudstor:aws"
    
    1. The db comes up as initialized with the image default settings.
    2. You edit the conf settings inside the container, e.g if you want to increase the maximum number of concurrent connections that requires a restart
    3. stop the running container (or scale the service down to zero and then back to one)
    4. the swarm spawns a new container, which this time around picks up your persisted configuration settings and merrily applies them.

    A pleasant side-effect of persisting your configuration is that it also persists your databases (or was it the other way around) ;-)

    0 讨论(0)
  • 2020-11-29 16:33

    My solution is for colleagues who needs to make changes in config before launching docker-entrypoint-initdb.d

    I was needed to change 'shared_preload_libraries' setting so during it's work postgres already has new library preloaded and code in docker-entrypoint-initdb.d can use it.

    So I just patched postgresql.conf.sample file in Dockerfile:

    RUN echo "shared_preload_libraries='citus,pg_cron'" >> /usr/share/postgresql/postgresql.conf.sample
    RUN echo "cron.database_name='newbie'" >> /usr/share/postgresql/postgresql.conf.sample
    

    And with this patch it become possible to add extension in .sql file in docker-entrypoint-initdb.d/:

    CREATE EXTENSION pg_cron;
    
    0 讨论(0)
提交回复
热议问题