postgres instalar container conf postgresql docker

postgresql - instalar - install postgres in docker container



¿Cómo personalizar el archivo de configuración de la imagen oficial de Docker PostgreSQL? (8)

Estoy usando la imagen oficial de Postgres Docker tratando de personalizar su configuración. Para este propósito, uso el comando sed para cambiar max_connections por ejemplo:

sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /var/lib/postgresql/data/postgresql.conf

Intenté dos métodos para aplicar esta configuración. El primero es agregar los comandos a un script y copiarlo dentro de la carpeta de inicio "/docker-entrypoint-initdb.d". El segundo método es ejecutarlos directamente dentro de mi Dockerfile con el comando "EJECUTAR" (este método funcionó bien con una imagen Postgresql no oficial con una ruta diferente al archivo de configuración "/ etc / postgres / ..."). En ambos casos, los cambios fallan porque falta el archivo de configuración (creo que aún no se ha creado).

¿Cómo debo cambiar la configuración?

Editar 1:

Aquí está el Dockerfile utilizado para crear la imagen:

# Database (http://www.cs3c.ma/) FROM postgres:9.4 MAINTAINER Sabbane <[email protected]> ENV TERM=xterm RUN apt-get update RUN apt-get install -y nano ADD scripts /scripts # ADD scripts/setup-my-schema.sh /docker-entrypoint-initdb.d/ # Allow connections from anywhere. RUN sed -i -e"s/^#listen_addresses =.*$/listen_addresses = ''*''/" /var/lib/postgresql/data/postgresql.conf RUN echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf # Configure logs RUN sed -i -e"s/^#logging_collector = off.*$/logging_collector = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_directory = ''pg_log''.*$/log_directory = ''//var//log//postgresql''/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_filename = ''postgresql-/%Y-/%m-/%d_/%H/%M/%S.log''.*$/log_filename = ''postgresql_/%a.log''/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_file_mode = 0600.*$/log_file_mode = 0644/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_truncate_on_rotation = off.*$/log_truncate_on_rotation = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_rotation_age = 1d.*$/log_rotation_age = 1d/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_min_duration_statement = -1.*$/log_min_duration_statement = 0/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_checkpoints = off.*$/log_checkpoints = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_connections = off.*$/log_connections = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_disconnections = off.*$/log_disconnections = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^log_line_prefix = ''/%t /[/%p-/%l/] /%q/%u@/%d ''.*$/log_line_prefix = ''/%t /[/%p/]: /[/%l-1/] user=/%u,db=/%d''/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_lock_waits = off.*$/log_lock_waits = on/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#log_temp_files = -1.*$/log_temp_files = 0/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#statement_timeout = 0.*$/statement_timeout = 1800000 # in milliseconds, 0 is disabled (current 30min)/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^lc_messages = ''en_US.UTF-8''.*$/lc_messages = ''C''/" /var/lib/postgresql/data/postgresql.conf # Performance Tuning RUN sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^shared_buffers =.*$/shared_buffers = 16GB/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#effective_cache_size = 128MB.*$/effective_cache_size = 48GB/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#work_mem = 1MB.*$/work_mem = 16MB/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#maintenance_work_mem = 16MB.*$/maintenance_work_mem = 2GB/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#checkpoint_segments = .*$/checkpoint_segments = 32/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#checkpoint_completion_target = 0.5.*$/checkpoint_completion_target = 0.7/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#wal_buffers =.*$/wal_buffers = 16MB/" /var/lib/postgresql/data/postgresql.conf RUN sed -i -e"s/^#default_statistics_target = 100.*$/default_statistics_target = 100/" /var/lib/postgresql/data/postgresql.conf VOLUME ["/var/lib/postgresql/data", "/var/log/postgresql"] CMD ["postgres"]

Con este Dockerfile, el proceso de compilación muestra el error: sed: can''t read /var/lib/postgresql/data/postgresql.conf: No such file or directory


Con Docker Compose

Cuando trabaje con Docker Compose, puede usar el command: postgres -c option=value en su docker-compose.yml para configurar Postgres.

Por ejemplo, esto hace que Postgres inicie sesión en un archivo:

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

Adaptando la respuesta de Vojtech Vitek , puede usar

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

para cambiar el archivo de configuración que Postgres usará. Montarías tu archivo de configuración personalizado con un volumen:

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

Aquí está el docker-compose.yml de mi aplicación, que muestra cómo configurar 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:

Permiso para escribir en el directorio de registro

Tenga en cuenta que cuando está en Linux, el directorio de registro en el host debe tener los permisos correctos. De lo contrario, obtendrá el error ligeramente engañoso

FATAL: no se pudo abrir el archivo de registro "/logs/postgresql-2017-02-04_115222.log": permiso denegado

Digo engañoso, ya que el mensaje de error sugiere que el directorio en el contenedor tiene un permiso incorrecto, cuando en realidad el directorio en el host no permite la escritura.

Para solucionar esto, configuro los permisos correctos en el host usando

chgroup ./logs docker && chmod 770 ./logs


Inyecte postgresql.conf personalizado en el contenedor Docker de postgres

El archivo postgresql.conf predeterminado se encuentra dentro del directorio PGDATA ( /var/lib/postgresql/data ), lo que hace las cosas más complicadas especialmente cuando se ejecuta el contenedor postgres por primera vez, ya que el contenedor docker-entrypoint.sh invoca el paso initdb para PGDATA directorio PGDATA .

Para personalizar la configuración de PostgreSQL en Docker de manera consistente, sugiero usar la opción config_file postgres junto con volúmenes de Docker como este:

Base de datos de producción (directorio PGDATA como volumen persistente)

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

Base de datos de prueba (el directorio PGDATA se descartará después de 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

Depuración

  1. Elimine -d (opción de docker run ) del comando de docker run para ver los registros del servidor directamente.
  2. Conéctese al servidor postgres con el cliente psql y consulte la configuración:

    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;


Cuando ejecuta el punto de entrada oficial (AKA cuando inicia el contenedor), ejecuta initdb en $PGDATA ( /var/lib/postgresql/data por defecto), y luego almacena en ese directorio estos 2 archivos:

  • postgresql.conf con la configuración manual predeterminada.
  • postgresql.auto.conf con configuraciones reemplazadas automáticamente con los comandos ALTER SYSTEM .

El punto de entrada también ejecuta cualquier /docker-entrypoint-initdb.d/*.{sh,sql} .

Todo esto significa que puede proporcionar un script de shell / SQL en esa carpeta que configura el servidor para el próximo inicio (que será inmediatamente después de la inicialización de la base de datos, o las próximas veces que inicie el contenedor).

Ejemplo:

archivo conf.sql :

ALTER SYSTEM SET max_connections = 6; ALTER SYSTEM RESET shared_buffers;

Archivo Dockerfile :

FROM posgres:9.6-alpine COPY *.sql /docker-entrypoint-initdb.d/ RUN chmod a+r /docker-entrypoint-initdb.d/*

Y luego tendrá que ejecutar conf.sql manualmente en bases de datos ya existentes. Como la configuración se almacena en el volumen, sobrevivirá a las reconstrucciones.

Otra alternativa es pasar -c flag tantas veces como desee:

docker container run -d postgres -c max_connections=6 -c log_lock_waits=on

De esta manera, no necesita crear una nueva imagen, y no necesita preocuparse por las bases de datos ya existentes o no; Todos se verán afectados.


La imagen postgres:9.4 que has heredado declara un volumen en /var/lib/postgresql/data . Esto esencialmente significa que no puede copiar ningún archivo a esa ruta en su imagen; Los cambios serán descartados.

Tienes algunas opciones:

  • Simplemente puede agregar sus propios archivos de configuración como volumen en tiempo de docker run -v postgresql.conf:/var/lib/postgresql/data/postgresql.conf ... Sin embargo, no estoy seguro exactamente cómo interactuará con el volumen existente.

  • Puede copiar el archivo cuando se inicia el contenedor. Para hacer eso, copie su archivo en la compilación en una ubicación que no esté debajo del volumen, luego llame a un script desde el punto de entrada o cmd que copiará el archivo a la ubicación correcta e iniciará postgres.

  • Clone el proyecto detrás de la imagen oficial de Postgres y edite el Dockerfile para agregar su propio archivo de configuración antes de que se declare el VOLUMEN (cualquier cosa agregada antes de que la instrucción VOLUME se copie automáticamente en tiempo de ejecución).

  • Pase todos los cambios de configuración en la opción de comando en el archivo docker-compose

me gusta:

services: postgres: ... command: - "postgres" - "-c" - "max_connections=1000" - "-c" - "shared_buffers=3GB" - "-c" ...


Mi solución es para colegas que necesitan hacer cambios en la configuración antes de iniciar docker-entrypoint-initdb.d

Tenía que cambiar la configuración de ''shared_preload_libraries'' para que, durante su trabajo, postgres ya tenga una nueva biblioteca precargada y el código en docker-entrypoint-initdb.d pueda usarla.

Así que simplemente parcheé el archivo postgresql.conf.sample en 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

Y con este parche es posible agregar extensión en el archivo .sql en docker-entrypoint-initdb.d /:

CREATE EXTENSION pg_cron;


Puede poner su postgresql.conf personalizado en un archivo temporal dentro del contenedor y sobrescribir la configuración predeterminada en tiempo de ejecución.

Para hacer eso :

  • Copie su postgresql.conf personalizado dentro de su contenedor
  • Copie el archivo /docker-entrypoint-initdb.d/ en /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

En tiempo de ejecución, el contenedor ejecutará el script dentro de /docker-entrypoint-initdb.d/ y sobrescribirá la configuración predeterminada con la personalizada.


Revisé todas las respuestas y queda otra opción. Puede cambiar su valor de CMD en el archivo acoplable (no es el mejor, pero sigue siendo la forma posible de lograr su objetivo).

Básicamente necesitamos

  • Copie el archivo de configuración en el contenedor docker
  • Anular las opciones de inicio de postgres

Ejemplo de archivo Docker:

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"]

Aunque creo que usar el command: postgres -c config_file=/etc/postgresql/postgresql.conf en su archivo docker-compose.yml propuesto por Matthias Braun es la mejor opción.


Una solución de baja tecnología para este problema parece ser declarar el servicio (estoy usando swarm en AWS y un archivo yaml) con sus archivos de base de datos montados en un volumen persistente (aquí AWS EFS como lo indica el controlador cloudstor: aws especificación).

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. El db aparece como inicializado con la configuración predeterminada de la imagen.
  2. Edita la configuración de conf dentro del contenedor, por ejemplo, si desea aumentar el número máximo de conexiones simultáneas que requieren un reinicio
  3. detener el contenedor en ejecución (o reducir el servicio a cero y luego volver a uno)
  4. el enjambre genera un nuevo contenedor, que esta vez recoge los ajustes de configuración persistentes y los aplica alegremente.

Un efecto secundario agradable de persistir en su configuración es que también persiste en sus bases de datos (o fue al revés) ;-)