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
-
Elimine
-d
(opción dedocker run
) del comando dedocker run
para ver los registros del servidor directamente. -
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 comandosALTER 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"
- El db aparece como inicializado con la configuración predeterminada de la imagen.
- 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
- detener el contenedor en ejecución (o reducir el servicio a cero y luego volver a uno)
- 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) ;-)