DOCKER SERIES: LAB … Dockerfile: LAYERS ( build )
Outro dia, outro post. Hoje responderemos não apenas uma, mas várias perguntas que ainda estão em aberto. Dentre elas, as principais:
- O que são imagens?
- Como as imagens se tornam containers?
- Como criar imagens próprias?
Ei Victor, essas aí já foram sanadas aqui … Não? Ãããã, como posso dizer? NÃO! Quero dizer, conceitualmente e bem superficialmente, SIM. Entretanto na prática e pormenores, a resposta continua sendo NÃO. Só que “não” por muito tempo … Afinal, vem comigo 🙃
Camadas : DOCKER LAYERS
Qualquer imagem no Docker é formada por um conjunto de camadas. Cada uma em si mesma é independente da outra. Tanto que recebem um identificador exclusivo e único para isso. Muito embora independentes, precisamos também enxergá-las como cascata. Em outras palavras, interligadas. Sim, sim, eu sei … Quase um paradoxo: segmentar para unir depois?! WTF? Bom, tentarei explicar 🤔 Tal “estranheza” ocorre pois em teoria cada camada olha diretamente para sua antecessora, e somente traz consigo eventuais mudanças/alterações nos respectivos sistemas de arquivos. Para que fique mais claro, por exemplo, a cada novo comando instruído no Dockerfile é criada uma nova camada. Veja a seguir:
FROM ubuntu:latest COPY foo.txt /foo.txt RUN date +%Y-%m-%d > /built-on.txt
Essa imagem hipotética apresenta duas instruções (copy
e run
), então consequentemente temos duas camadas. Resumindo brevemente:
- A primeira etapa copia
foo.txt
em uma nova camada baseada na imagemubuntu:latest
. - A segunda etapa executa o comando
date
e canaliza sua saída para um arquivo. Isso cria uma segunda camada baseada na anterior.
Imagens : DOCKER HISTORY
Felizmente existe um comando específico para inspecionar e trazer mais detalhes sobre as imagens e suas camadas. Trata-se do docker history
Contudo, antes você precisa do id da mesma, sendo assim execute:
docker images

Para depois informá-lo através de:
docker history f589ccde7957

Reparem que certas camadas, aonde não há “grandes” operações (ex: copia de arquivos, download de artefatos), o tamanho fica reduzido a zero absoluto. Além disso, veremos que a vantagem do Docker é justamente a reutilização de camadas por parte de outras imagens baseadas na primeira. Ou seja, não somos obrigados a baixar uma imagem inteira! A partir de agora você será capaz de selecionar apenas o que lhe interessa, seja a camada 01, 02, 03 ou 04, por exemplo.
Container = R/W (read & write) … Imagem = R/O (read only)
Para avançarmos um pouco, preciso que fixem na memória a diferença entre imagem e container. Simplificando bastante:
- Uma imagem nada mais é do que um container “parado” e portanto, uma enorme camada READ ONLY
- Um container trata-se de uma imagem em execução, apresentando assim duas grandes camadas, sendo que a principal é a de READ/WRITE
Talvez por isso que o Docker consegue ser uma aplicação tão leve e rápida, já que eu posso muito bem ter 1, 10, 100, 1000 containers rodando na máquina. Mas se todos forem baseadas na mesma imagem, o sistema terá carregado apenas ela e compartilhado com cada um. Para ilustrar melhor, observem a(s) figura(s):


Dockerfile : DOCKER BUILD
Agora é a hora da verdade! Vamos efetivamente criar a nossa primeira imagem. Trata-se de uma simples (porém charmosa) página web, exibindo uma mensagem ao usuário. Para isso utilizaremos um pouco das linguagens HTML, CSS, NodeJS. Visando facilitar o trabalho de todos, criei um repositório no GitHub e sendo assim qualquer pessoa pode cloná-lo. Aqui não irei entrar em detalhes sobre programação, linguagem nem nada do tipo. Esse não é o foco! Nos atemos a questão da infraestrutura, ou melhor, traduzindo: como disponibilizá-la da melhor maneira possível. E usando o Docker, é claro 🙂
Passo um – Clonar o repositório
git clone https://github.com/vicrlda/nodejs-sample.git
Passo dois – Adicionar um novo arquivo chamado Dockerfile
vim Dockerfile

Passo três – Editá-lo com o seguinte conteúdo
FROM node:14 WORKDIR /app-node COPY . . RUN npm install ENTRYPOINT npm start
Passo quatro – Montar a imagem, passando um nome e uma tag
docker build -t vicrlda/app-node:1.0 .

Passo cinco – Listar novamente todas as imagens, incluindo a nossa recém-criada
sudo docker images

Passo seis – Executar um novo container baseado na nossa própria imagem
sudo docker run -d -p 8080:3000 vicrlda/app-node:1.0

http://localhost:8080/

Até 2023 😃 Feliz Ano Novo!
REFERÊNCIAS:
https://docs.docker.com/engine/reference/builder/
https://www.howtogeek.com/devops/what-are-docker-image-layers/