>> Apresentação e considerações
Antes de começar a pensar em ambientes complexos, escaláveis, em Cluster, com LoadBalancer tudo o que envolve a arquitetura de um projeto em que vai ser utilizado Docker precisamos ter bases bem sólidas pois a sua base pode determinar muitas vezes o sucesso ou o fracasso do seu projeto.
O seu ambiente e o seu projeto só vai existir se você tiver imagens, sem imagem não existe containers, temos também um outro paralelo, onde, uma imagem sem uma configuração adequada ou poluída afeta diretamente o resultado do seu projeto deixando muitos lixos, arquivos e pacotes desnecessários.
Construir uma imagem no Docker chega a ser uma tarefa na maioria das vezes muito simples, porém é necessário se atentar há algumas regras que fazem toda a diferença.
Nesse artigo vamos conhecer o que é Dockerfile e indicar algumas boas práticas decisivas para a construção da sua imagem, espero que gostem…
Let’s go!!!
>> O que é Dockefile?
Dockerfile
é o arquivo de build das imagens Docker, ele é escrito com uma syntax simples no formato “YML” ou “YAML”.
O nome precisa essencialmente ser "Dockerfile"
pois ao executar o "docker build"
ele entende que é o arquivo e executa as instruções contidas nele
Como assim arquivo de build?
Bem, imagina ele como um script, onde você passa as instruções e as executa para ter o resultado esperado, no caso do Dockerfile ele possui uma série de opções bem definidas que tornam muito simples a construção de uma imagem, nele você declara a sua imagem base, quais pacotes serão instalados ou removidos, envio de arquivos e/ou diretórios, adição de variáveis de ambiente e muito mais, ou seja, tudo o que você precisa para ter para que a sua aplicação funcione, ao executá-lo o resultado será uma imagem personalizada que depois você pode guardar no Dockerhub
por exemplo ou no seu Registry privado
para utilizar quando precisar para subir seus containers.
>> Exemplificando e construindo a primeira imagem
Crie o diretório que conterá seu Dockerfile e em seguida criei o arquivo
~$ mkdir Docker-nginx; cd Docker-nginx ~$ vim Dockerfile
Copie e cole o conteúdo abaixo dentro do seu Dockerfile
# Chama a imagem "ubuntu:16.04" como imagem base para o build # O FROM é obrigatório no início FROM ubuntu:16.04 # Atualizado o repo, instala o NGINX e remove o cache do APT RUN apt-get update -y && apt-get install nginx -y \ && rm -rf /var/lib/apt/lists/* # Inicia o NGINX quando o container for executado CMD ["nginx", "-g", "daemon off;"]
Agora pra validar se está vamos criar a nossa imagem criando uma tag com o parâmetro -t
$ docker build -t churrops/nginx:1.0.0 .
Se ao final do build aparecer essa mensagem, você está no caminho certo!
Successfully built 7c33dad1a649 Successfully tagged churrops/nginx:1.0.0
Agora vamos listar a nossa imagem, e em seguida iniciar o nosso container
$ docker image ls |grep churrops/nginx churrops/nginx 1.0.0 7c33dad1a649 About a minute ago 177MB
$ docker container run -d -p 80:80 --name churrops-nginx churrops/nginx:1.0.0 f7acfa15accc354df7600a860b34977765484854215ce061863b8f64cef09108
$ docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f7acfa15accc churrops/nginx:1.0.0 "nginx -g 'daemon ..." 47 seconds ago Up 46 seconds 0.0.0.0:80->80/tcp churrops-nginx
Agora, ao abrir no browser vemos que a nossa primeira imagem está ok!
Vamos remover o nosso container para prosseguir no artigo.
~$ docker container rm -f churrops-nginx
>> Algumas observações que temos que ter em mente
- Os containers devem ser efêmeros, ou seja, nascem pra morrer, então sua imagem precisa estar preparada pra isso.
- Use um arquivo
.dockerignore
. O.dockerignore
possui a mesma funcionalidade do.gitignore
, fazendo com que você possa gerar a sua imagem excluindo alguns arquivos que estejam no diretório do seu Dockerfile. - Evite instalar pacotes desnecessários. Lembre-se que o container precisa ter somente o básico e necessário para o funcionamento da sua APP
- Cada container deve rodar apenas um processo principal. Não faz sentido você ter um container rodando diversas aplicações
- Minimize o número de camadas ou layers. Cada
RUN
,COPY
,ADD
por exemplo cria uma camada - Quebrar argumentos grandes em várias linhas utilizando barra invertida
\
- Sempre usar
TAGS
quando for fazer obuild
das imagens - Build cache – build-cache
>> Conhecendo os parâmetros do Dockerfile
Cientes do que é um Dockerfile vamos conhecer os seus parâmetros, vou adicionar algumas informações a respeito das boas práticas, mais claro sempre procurem ler a documentação oficial para entender mais a fundo alguns parâmetros.
FROM
Define qual imagem base a ser utilizada para iniciar o estágio de compilação, ao executar o "docker build"
essa imagem precisa estar acessível, pois o Docker irá realizar o pull
e somente com a imagem no local ele irá seguir para os demais estágios, lembrando que recentemente agora podemos utilizar mais de um FROM
no mesmo Dockerfile para a realização de build Multi-Stage
Recomendações: Sempre procure utilizar imagens
OFICIAIS
ou imagens da sua confiança
RUN
A imagem base é a primeira camada da construção, o RUN
inicia uma nova camada, e nele você pode executar N
comandos, basicamente o que você faria logado na instância ele faz, seja um apt-get
, yum
, rm
, etc, com o RUN você passa as instruções do que será construído em tempo de execução do Dockerfile
Recomendações: Para tornar seu Dockerfile mais legível, compreensível e sustentável, divida instruções
RUN
longas ou complexas em várias linhas separadas com barras invertidas\
e use o mínimo de RUN possível, pois a cada RUN é gerada uma camada na imagem.
Vamos ver um exemplo de uso ineficaz do RUN, dessa forma ao executar o primeiro RUN a compilação cria uma camada ReadOnly onde o próximo RUN não limpa de fato o cache do apt da imagem, quando subimos um container com essa imagem “aparentemente”os arquivos não estão lá, mas na verdade só não estamos vendo, mais o lixo está fixo na camada anterior deixando a imagem “suja”.
RUN apt-get update -y RUN apt-get install -y package-bar package-baz package-foo -y RUN rm -rf /var/lib/apt/lists/*
Agora vamos melhorar o nosso RUN, dessa forma melhoramos a aparência do RUN quebrando as linhas com barra invertida e ainda garantimos que estamos removendo o lixo de fato da imagem
RUN apt-get update && apt-get install -y \ package-bar \ package-baz \ package-foo \ && rm -rf /var/lib/apt/lists/*
LABEL
Adiciona metadados a uma imagem no formato chave-valor, é extremamente importante para identificação da imagem e inclusive para automação é muito utilizado.
Exemplos:
# Setando 1 ou mais LABELs individuais LABEL com.example.version="0.0.1-beta" LABEL vendor="ACME Incorporated" # Setando multiplos LABLEs em uma mesma linha LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12" # Set multiple labels at once, using line-continuation characters to break long lines LABEL vendor=ACME\ Incorporated \ com.example.is-beta= \ com.example.is-production=""
MAINTAINER (deprecated)
Opção para definir o mantenedor da imagem, porém ela foi substituída pelo LABEL.
EXPOSE
Expõe as portas de escuta do container especificadas na execução, porém o EXPOSE no Dockerfile não faz o BIND com a porta do host fazendo a exposição, isso precisa ser feito ou em um Compose File ou no start do Container com o parâmetro "-p 80:80"
, ou seja, jamais coloque EXPOSE 80:80
assim no seu Dockerfile
ENV
Variáveis de ambiente a serem enviadas para a imagem
COPY
Copia os arquivos do diretório especificado do host para o diretório especificado dentro do container
ADD
O ADD além de copiar também arquivos do local ele serve para enviar arquivos empacotados com “tar” na origem e automaticamente descompactar no destino e também tem a capacidade de baixar arquivos de uma URL, desde que não tenha autenticação.
ENTRYPOINT
É o ponto de entrada quando você iniciar o container, ou seja, geralmente definimos no ENTRYPOINT o comando ou script que chama o processo responsável pela execução do container e que manterá o container vivo.
CMD
Geralmente é utilizado para prover argumentos para o ENTRYPOINT, quando você usa o CMD sem ENTRYPOINT o CMD é o que vale no start do container, quando você tem CMD e ENTRYPOINT no mesmo DockerFile, o que é colocado no CMD geralmente são parâmetros complementares para o ENTRYPOINT
VOLUME
Instrução que fala qual volume será mapeado ou criado para o container
USER
Nome de usuário (ou UID) e, opcionalmente, o grupo de usuários (ou GID) a serem usados ao executar a imagem e as instruções RUN, CMD e ENTRYPOINT que o seguem no Dockerfile.
WORKDIR
Diretório à partir de onde os comandos ou as ações serão realizadas durante a contrução da imagem, para maior clareza e confiabilidade, você sempre deve usar caminhos absolutos para o seu WORKDIR.
ARG
Define uma variável que os usuários podem passar no tempo de compilação para o construtor com o comando de compilação docker usando o sinalizador --build-arg =
ONBUILD
Define algumas instruções que podem ser realizadas quando alguma determinada ação for executada, é basicamente como uma trigger.
STOPSIGNAL
Define o sinal de chamada do sistema que será enviado para o contêiner para sair. Este sinal pode ser um número não assinado válido que coincide com uma posição na tabela syscall do kernel, por exemplo, 9 ou um nome de sinal no formato SIGNAME, por exemplo SIGKILL.
HEALTHCHECK
A instrução HEALTHCHECK diz ao Docker como testar um container para verificar se ele ainda está funcionando. Isso pode detectar casos como um servidor web que está preso em um loop infinito e incapaz de lidar com novas conexões, mesmo que o processo do servidor ainda esteja em execução.
SHELL
Serve para definir ou mudar no caso o SHELL padrão para a execução dos comandos, no linux o padrão é o ["/bin/sh", "-c"]
e no Windows ["cmd", "/S", "/C"]
>> Exemplos de Dockerfile
Segue exemplos de Dockerfiles de fontes oficiais para que vocês possam ter uma base e acredito que com isso já podemos ter uma boa idéia de como funciona!
Dockerfile | WordPress Oficial
>> Build
O próximo passo da criação de um Dockerfile é justamente o buid, que pode ser usado em sua forma mais básica, como fizemos lá no início do tutorial, lembre-se que a TAG
no build
é extremamente importante.
Acredito que o assunto build
pode até virar um artigo futuramente, de qualquer forma, segue a documentação a respeito para consulta:
https://docs.docker.com/engine/reference/commandline/build/
>> Conclusão
É isso ChurrOpeiros, procurei abordar algumas das boas práticas para a contrução de Dockerfile de acordo com a documentação, e é claro, sempre leiam a documentação pois vocês sempre estarão atualizados e sincronizados com as mudanças, acho espero ter conseguido passar a mensagem!
FeedBacks são bem vindos, gostou desse artigo? Ajude-nos COMPARTILHANDO nas suas redes sociais!
Abraços!
>> Referências
https://docs.docker.com/engine/reference/builder/
https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/
29/09/2017 at 4:15 pm
showw de bola….como sempre detalhado, linguagem simples e de fácil compreensão.
CurtirCurtido por 1 pessoa