Cómo crear Usuario / Base de datos en script para Docker Postgres


He estado tratando de configurar un contenedor para una instancia de postgres de desarrollo mediante la creación de una base de datos de usuario personalizada. Estoy usando la imagen docker oficial de postgres. En la documentación le indica que inserte un script bash dentro de la carpeta /docker-entrypoint-initdb.d/ para configurar la base de datos con cualquier parámetro personalizado.

Mi script bash: make_db.sh

su postgres -c "createuser -w -d -r -s docker"
su postgres -c "createdb -O docker docker"

Dockerfile

FROM library/postgres

RUN ["mkdir", "/docker-entrypoint-initdb.d"]
ADD make_db.sh /docker-entrypoint-initdb.d/

El error que obtengo de docker logs -f db (db es el nombre de mi contenedor) es:

Createuser: no se pudo conectar a la base de datos postgres: no se pudo conectar al servidor: No existe dicho archivo o directorio

Parece que los comandos dentro de la carpeta /docker-entrypoint-initdb.d/ se están ejecutando antes de que se inicie postgres. Mi pregunta es, ¿cómo configuro un usuario/base de datos mediante programación usando el contenedor oficial de postgres? ¿Hay alguna manera de hacer esto con un guión?

Author: Soviut, 2014-10-28

4 answers

EDITAR - desde el 23 de julio de 2015

La imagen docker oficial de postgres ejecutará .sql scripts encontrados en la carpeta /docker-entrypoint-initdb.d/.

Así que todo lo que necesita es crear el siguiente script sql:

init.sql

CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;

Y añadirlo en su Dockerfile:

Dockerfile

FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/

Pero desde el 8 de julio de 2015, si todo lo que necesita es crear un usuario y una base de datos , es más fácil hacer uso de la POSTGRES_USER, POSTGRES_PASSWORD y POSTGRES_DB variables de entorno:

docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres

O con un Dockerfile:

FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker

Para imágenes anteriores a Jul 23, 2015

De la documentación de la imagen de postgres Docker , se dice que

[...] obtendrá la fuente de cualquier script *.sh que se encuentre en ese directorio [/docker-entrypoint-initdb.d] para realizar una inicialización adicional antes de iniciar el servicio

Lo importante aquí es "antes de iniciar el servicio". Esto significa que su guión make_db.sh se ejecutará antes de que se inicie el servicio postgres, de ahí el mensaje de error "no se pudo conectar a la base de datos postgres".

Después de eso hay otra información útil: {[18]]}

Si necesita ejecutar comandos SQL como parte de su inicialización, se recomienda encarecidamente el uso del modo Postgres single user.

De acuerdo esto puede ser un poco misterioso a la primera mirada. Lo que dice es que su el script de inicialización debe iniciar el servicio postgres en modo único antes de realizar sus acciones. Así que podrías cambiar tu make_db.ksh script de la siguiente manera y debería acercarte a lo que quieres: {[18]]}

NOTA, esto ha cambiado recientemente en el siguiente commit. Esto funcionará con el último cambio:

export PGUSER=postgres
psql <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

Anteriormente, se requería el uso del modo --single:

gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
 231
Author: Thomasleveil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-26 14:22:30

Ahora puede poner .archivos sql dentro del directorio init:

De los documentos

Si desea realizar una inicialización adicional en una imagen derivada de esta, agregue uno o más *.scripts sql o *.sh bajo / docker-entrypoint-initdb.d (crear el directorio si es necesario). Después de que entrypoint llame a initdb para crear el usuario y la base de datos predeterminados de postgres, ejecutará cualquier *.archivos sql y código fuente cualquier*. sh scripts encontrados en ese directorio para hacer más inicialización antes de iniciar el servicio.

Así que copiando su.el archivo sql en funcionará.

 11
Author: m0meni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-29 16:42:44

Agrego comandos personalizados a un entorno evocado en un CMD después de iniciar servicios... No lo he hecho con postgres, pero con Oracle:

#set up var with noop command
RUN export POST_START_CMDS=":"
RUN mkdir /scripts
ADD script.sql /scripts
CMD service oracle-xe start; $POST_START_CMDS; tail -f /var/log/dmesg

Y empezar con

docker run -d ... -e POST_START_CMDS="su - oracle -c 'sqlplus @/scripts/script' " <image>

.

 5
Author: Rondo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-28 03:13:55

Necesita tener la base de datos ejecutándose antes de crear los usuarios. Para ello se necesitan múltiples procesos. Puede iniciar postgres en un subshell ( & ) en el script de shell, o usar una herramienta como supervisord para ejecutar postgres y luego ejecutar cualquier script de inicialización.

Una guía para supervisord y docker https://docs.docker.com/articles/using_supervisord /

 3
Author: seanmcl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-28 00:39:41