start postgres initdb entrypoint create compose bash postgresql docker dockerhub

bash - initdb - postgresql image



Cómo crear usuario/base de datos en script para Docker Postgres (6)

EDITAR - desde el 23 de julio de 2015

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

Entonces, 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 agréguelo 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 usar las variables de entorno POSTGRES_USER , POSTGRES_PASSWORD y POSTGRES_DB :

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 al 23 de julio de 2015

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

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

Lo importante aquí es "antes de comenzar el servicio" . Esto significa que su script make_db.sh se ejecutará antes de que se inicie el servicio postgres, por lo tanto, el mensaje de error "no se pudo conectar a la base de datos postgres" .

Después de eso hay otra información útil:

Si necesita ejecutar comandos SQL como parte de su inicialización, se recomienda el uso del modo de usuario único de Postgres.

De acuerdo, esto puede ser un poco misterioso a primera vista. Lo que dice es que su script de inicialización debe iniciar el servicio postgres en modo único antes de realizar sus acciones. Por lo tanto, puede cambiar su script make_db.ksh de la siguiente manera y debería acercarse a lo que desea:

NOTA , esto ha cambiado recientemente en la siguiente confirmación . 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

He estado tratando de configurar un contenedor para una instancia de postgres de desarrollo creando un usuario y una base de datos personalizados. Estoy usando la imagen oficial de docker 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 los docker logs -f db de la 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 tal 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 script?


Agrego comandos personalizados a un entorno evocado en un CMD después de iniciar los 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 comenzar con

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

.


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 en /docker-entrypoint-initdb.d (creando el directorio si es necesario). Después de que el punto de entrada llama a initdb para crear el usuario y la base de datos predeterminados de postgres, ejecutará cualquier archivo * .sql y generará cualquier script * .sh que se encuentre en ese directorio para realizar una inicialización adicional antes de iniciar el servicio.

Así que copiar su archivo .sql funcionará.


Al usar docker-compose :

Suponiendo que tiene el siguiente diseño de directorio:

$MYAPP_ROOT/docker-compose.yml /Docker/init.sql /Docker/db.Dockerfile

Archivo: docker-compose.yml

version: "3.3" services: db: build: context: ./Docker dockerfile: db.Dockerfile volumes: - ./var/pgdata:/var/lib/postgresql/data ports: - "5432:5432"

Archivo: Docker/init.sql

CREATE USER myUser; CREATE DATABASE myApp_dev; GRANT ALL PRIVILEGES ON DATABASE myApp_dev TO myUser; CREATE DATABASE myApp_test; GRANT ALL PRIVILEGES ON DATABASE myApp_test TO myUser;

Archivo: Docker/db.Dockerfile

FROM postgres:11.5-alpine COPY init.sql /docker-entrypoint-initdb.d/

Servicios de composición e inicio:

docker-compose -f docker-compose.yml up --no-start docker-compose -f docker-compose.yml start


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

Una guía para el supervisor y el acoplador https://docs.docker.com/articles/using_supervisord/


Puedes usar estos comandos:

docker exec -it yournamecontainer psql -U postgres -c "CREATE DATABASE mydatabase ENCODING ''LATIN1'' TEMPLATE template0 LC_COLLATE ''C'' LC_CTYPE ''C'';" docker exec -it yournamecontainer psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE postgres TO postgres;"