Como criar usuário / database no script para o Docker Postgres

Eu tenho tentado configurar um contêiner para uma instância postgres de desenvolvimento, criando um usuário personalizado & database. Estou usando a imagem do docker postgres oficial . Na documentação, ele instrui você a inserir um script bash dentro da pasta /docker-entrypoint-initdb.d/ para configurar o database com qualquer parâmetro personalizado.

Meu 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/ 

O erro que recebo dos docker logs -f db do docker logs -f db (db é o nome do meu contêiner) é:

createuser: não pôde se conectar a postgres de database: não foi possível conectar ao servidor: nenhum arquivo ou diretório

Parece que os comandos dentro da pasta /docker-entrypoint-initdb.d/ estão sendo executados antes que o postgres seja iniciado. Minha pergunta é: como configurar um usuário / database programaticamente usando o contêiner postgres oficial? Existe alguma maneira de fazer isso com um script?

EDIT – desde 23 de julho de 2015

A imagem oficial do docker postgres executará scripts .sql encontrados na pasta /docker-entrypoint-initdb.d/ .

Então tudo que você precisa é criar o seguinte script sql:

init.sql

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

e adicione-o no seu Dockerfile:

Dockerfile

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

Mas desde 8 de julho de 2015, se tudo o que você precisa é criar um usuário e um database , é mais fácil usar apenas as variables ​​de ambiente POSTGRES_USER , POSTGRES_PASSWORD e POSTGRES_DB :

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

ou com um Dockerfile:

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

para imagens com mais de 23 de julho de 2015

A partir da documentação da imagem do Docker postgres , diz-se que

[…] ele irá fornecer qualquer script * .sh encontrado nesse diretório [ /docker-entrypoint-initdb.d ] para fazer uma boot adicional antes de iniciar o serviço

O que é importante aqui é “antes de iniciar o serviço” . Isso significa que seu script make_db.sh será executado antes do serviço postgres ser iniciado, portanto, a mensagem de erro “não pôde se conectar a postgres do database” .

Depois disso, há outra informação útil:

Se você precisar executar comandos SQL como parte de sua boot, o uso do modo de usuário único do Postgres é altamente recomendado.

Acordado isso pode ser um pouco misterioso no primeiro olhar. O que ele diz é que seu script de boot deve iniciar o serviço postgres no modo único antes de executar suas ações. Assim, você pode alterar o seu script make_db.ksh da seguinte forma e deve aproximá-lo do que deseja:

NOTA , isso mudou recentemente no commit seguinte . Isso funcionará com a última alteração:

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

Anteriormente, o uso do modo - único era necessário:

 gosu postgres postgres --single <<- EOSQL CREATE USER docker; CREATE DATABASE docker; GRANT ALL PRIVILEGES ON DATABASE docker TO docker; EOSQL 

Agora você pode colocar arquivos .sql dentro do diretório init:

Dos docs

Se você quiser fazer uma boot adicional em uma imagem derivada desta, adicione um ou mais scripts * .sql ou * .sh em /docker-entrypoint-initdb.d (criando o diretório, se necessário). Depois que o entrypoint chama o initdb para criar o database e o usuário postgres padrão, ele executará todos os arquivos * .sql e fornecerá qualquer script * .sh encontrado nesse diretório para fazer uma boot adicional antes de iniciar o serviço.

Então, copiar seu arquivo .sql funcionará.

Eu adiciono comandos personalizados a um ambiente evocado em um CMD depois de iniciar serviços … Eu não fiz isso com postgres, mas com o 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 

e comece com

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

.

Você precisa ter o database em execução antes de criar os usuários. Para isso, você precisa de vários processos. Você pode iniciar o postgres em um subshell (&) no shell script ou usar uma ferramenta como o supervisord para executar o postgres e depois executar qualquer script de boot.

Um guia para supervisord e docker https://docs.docker.com/articles/using_supervisord/