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:
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;"