Estou escrevendo um Dockerfile para o trabalho que instala o Postgresql e configura um banco de dados. Eu encontrei algumas pegadinhas ao longo do caminho. Aqui está a documentação de meus equívocos e as soluções.
Uma linha VS várias linhas
Originalmente, eu estava usando um comando RUN por linha de shell que queria executar:
Exemplo:
RUN service postgresql start
RUN su postgres -c "createuser -d -r -s root"
O problema
Eu queria separar os comandos para otimizar a recriação de outras imagens. Mas sempre recebo o erro de que o postgres não está funcionando. Isso é exatamente porque cada comando RUN é uma camada separada da máquina em execução. Iniciar o postgres em um comando RUN não faz nada porque assim que o próximo comando RUN é alcançado, estou em uma nova VM e não há postgres em execução.
A solução
Comandos de junção que fazem parte de um passo de configuração coeso em uma instrução RUN:
(Observe, obrigado @outrunthewolf por apontar que continuações de linha podem ser usadas para transportar o mesmo comando em várias linhas para facilitar a leitura).
RUN service postgresql start &&
su postgres -c "createuser -d -r -s root"
sudo
VS su
O problema
Os guias online para instalação e configuração do postgres instruem o usuário a executar comandos como sudo
, mas isso não funcionará com um Dockerfile porque os comandos estão sendo executados como root e o root não tem acesso ao sudo
comando.
A solução
Use para executar comandos como um usuário diferente.su {USER} -c "commands go here"
Um exemplo de Dockerfile
Aqui está um exemplo de Dockerfile que instala o postgresql, cria uma root
função e cria um banco de dados chamado accounts
.
FROM ubuntu
MAINTAINER Murphy Randle, murphy@spacemonkey.com
# Install Postgresql deps
RUN apt-get install -y postgresql postgresql-contrib
# Postgresql setup:
RUN service postgresql start && su postgres -c "createuser -d -r -s root" && createdb accounts && service postgresql stop
ENTRYPOINT ["/bin/bash"]