Criando containers Docker com o padrão de Docker-Entrypoint.sh

Há uma padrão para construção de imagens Docker que é muito útil em cenários quando existe a necessidade de rodar comandos logo que o container é criado e não na geração da imagem. Esse padrão pode ser chamado de docker-entrypoint.

Qual a diferença entre CMD e ENTRYPOINT

O ENTRYPOINT é o principal comando a ser executado quando o container sobe. Ele deve ser, inclusive, um comando que prende o terminal, caso contrário o container apenas sobe e desce não se mantendo útil. Esse comando deve receber um array ou mesmo um parâmetro único. O CMD, por sua vez, é muito parecido com o ENTRYPOINT e podemos dizer que possui as mesmas funções, porém, ele é opcional, ao contrário do ENTRYPOINT.

É fundamental entender que o ENTRYPOINT é sempre chamado e o CMD pode ser chamado ou não, veja o exemplo abaixo:

FROM        node:12.18.1   # imagem meunode
VOLUME      /app
WORKDIR     /app

COPY        docker-entrypoint.sh /
ENTRYPOINT  ["/docker-entrypoint.sh"]

EXPOSE      80
CMD         ["nodemon", "app.js" ]

Nesse exemplo o docker-entrypoint.sh é sempre executado, não importando o que for chamado por parâmetro na execução do container, já o comando “nodemon app.js” pode ser substituído pelo parâmetro passado. Veja o exemplo a seguir

docker run --name meucontainer -it -v /home/app:/app meunode
// Nesse caso o docker-entrypoint.sh é chamado e o comando 'nodemon app.js' também

Por outro lado é possível fazer o seguinte

 docker run --name meucontainer -it -v /home/app:/app meunode bash
// Nesse caso o docker-entrypoint.sh mas ao invés de chamar o 'nodemon app.js' quem é chamado é o bash

Porque utilizar o padrão docker-entrypoint

Observe que no exemplo da imagem meunode, criada acima, ele utiliza como entrypoint o docker-entrypoint.sh

Isso é especialmente útil nesse cenário onde há um volume compartilhado. Como a pasta /app é compartilhada não é possível usar o comando RUN npm install já que a imagem não sabe os dados do volume na sua criação. Em cenários como esse o docker-entrypoint.sh é obrigatório.

Veja a seguir o docker-entrypoint.sh

#!/bin/sh
# vim:sw=4:ts=4:et
set -e

echo "Docker-Entrypoint iniciado"
cd /app
npm install
npm install -g nodemon

echo "Docker-Entrypoint finalizado"

exec "$@"

O docker-entrypoint.sh executa os comandos npm install (instala todas as dependências externas de um projeto node) e npm install -g nodemon (instala a ferramenta nodemon de forma que ela fique acessível por todo o computador.) Esses comandos simplesmente não funcionariam no DOCKERFILE com os comandos RUN.

Po fim, há algo muito comum nesse arquivo que merece um destaque: a linha exec “$@”. Ela é responsável por pegar os parâmetros extras passados no comando docker run… (ou comandos afins) e executar. Entenda que quando o Docker Run é chamado diretamente, esse exec é ignorado e o CMD é executado; porém quando há um comando bash, por exemplo, ele é executado e o CMD não é.


Thiago Anselme
Thiago Anselme - Gerente de TI - Arquiteto de Soluções

Ele atua/atuou como Dev Full Stack C# .NET / Angular / Kubernetes e afins. Ele possui certificações Microsoft MCTS (6x), MCPD em Web, ITIL v3 e CKAD (Kubernetes) . Thiago é apaixonado por tecnologia, entusiasta de TI desde a infância bem como amante de aprendizado contínuo.

Deixe um comentário