M05·02Docker

CAPÍTULO 02

Docker

Imagens, containers, camadas, Dockerfile e os comandos que você vai usar todo dia.

Por Thiago Souza12 min de leituraAtualizado em 2026-05

O que é Docker?

Docker é a ferramenta que popularizou os containers. Ele é dois conceitos juntos:

  1. Um formato padrão para empacotar aplicações em imagens
  2. Uma engine que roda essas imagens como containers

Hoje em dia tem outras alternativas (Podman, containerd, CRI-O), mas Docker virou sinônimo de container — então vamos focar nele.

Como funciona Docker?

Docker usa três recursos do kernel Linux para criar a "ilusão" de que cada container é uma máquina isolada:

  1. Namespaces: Isolam o que o processo enxerga (PIDs, rede, sistema de arquivos, hostname). É como dar óculos pro container que só mostram parte da realidade.
  2. Cgroups (control groups): Limitam quanto cada container pode usar de CPU, memória, I/O, rede.
  3. Union Filesystem: Permite que imagens sejam construídas em camadas que se sobrepõem.

Não precisa decorar isso, mas é útil saber que container não é mágica — é Linux usando suas próprias features de forma esperta.

Imagem vs Container — a confusão clássica

Essa é a pergunta que todo iniciante faz. A resposta mais clara:

Imagem está para Container assim como Classe está para Objeto.

  • Imagem: Um pacote estático, imutável, com tudo que sua aplicação precisa. É um "template" salvo em disco.
  • Container: Uma instância em execução dessa imagem. É a imagem "ligada", rodando.

Você pode ter uma imagem nginx e rodar 10 containers a partir dela. Cada container é independente.

flowchart TD
  I["Imagem nginx<br/>receita do bolo"] -->|"docker run"| C1[cont1]
  I --> C2[cont2]
  I --> C3[cont3]
  I --> C4[cont4]

Camadas (Layers)

Imagens Docker são feitas de camadas empilhadas. Cada instrução do Dockerfile cria uma camada nova.

flowchart BT
  L1["camada 1: FROM golang:1.26<br/>raramente muda"] --> L2["camada 2: COPY go.mod"]
  L2 --> L3["camada 3: RUN go mod download<br/>muda às vezes"]
  L3 --> L4["camada 4: COPY app.go<br/>muda toda hora"]

Quando você muda só o código, as camadas de baixo já estão em cache, e o build fica muito mais rápido. Esse é um dos truques mais importantes para Dockerfiles eficientes.

Dockerfile — a receita

Um Dockerfile é o arquivo que descreve passo a passo como construir sua imagem.

dockerfile
# A imagem base — ponto de partida
FROM golang:1.26-alpine
 
# Define o diretório de trabalho dentro do container
WORKDIR /app
 
# Copia os arquivos de dependência primeiro (cache!)
COPY go.mod go.sum ./
RUN go mod download
 
# Agora copia o resto do código
COPY . .
 
# Compila a aplicação
RUN go build -o servidor .
 
# Documenta que o container expõe a porta 8080
EXPOSE 8080
 
# Comando que roda quando o container inicia
CMD ["./servidor"]

Principais instruções do Dockerfile

InstruçãoO que faz
FROMDefine a imagem base (todo Dockerfile começa com isso)
WORKDIRDefine o diretório de trabalho dentro do container
COPYCopia arquivos do host para a imagem
RUNExecuta um comando durante o build
ENVDefine variáveis de ambiente
EXPOSEDocumenta qual porta o container usa (não abre, só documenta)
CMDComando padrão que roda quando o container inicia
ENTRYPOINTSimilar ao CMD, mas mais "fixo" (não sobrescreve fácil)

Comandos Docker que você usa todo dia

bash
# Construir uma imagem a partir do Dockerfile na pasta atual
docker build -t minha-app:v1 .
 
# Listar imagens
docker images
 
# Rodar um container
docker run -d -p 8080:8080 --name meu-container minha-app:v1
 
# Listar containers rodando
docker ps
 
# Listar todos (incluindo parados)
docker ps -a
 
# Ver logs de um container
docker logs meu-container
 
# Entrar dentro do container (debug)
docker exec -it meu-container sh
 
# Parar um container
docker stop meu-container
 
# Remover um container parado
docker rm meu-container
 
# Remover uma imagem
docker rmi minha-app:v1

Decifrando o docker run

docker run -d -p 8080:8080 --name meu-container minha-app:v1
           │   │            │                    │
           │   │            │                    └─ qual imagem usar
           │   │            └─ nome amigável pro container
           │   └─ mapeia porta do host:container
           └─ "detached" — roda em segundo plano