O que é Docker?
Docker é a ferramenta que popularizou os containers. Ele é dois conceitos juntos:
- Um formato padrão para empacotar aplicações em imagens
- 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:
- Namespaces: Isolam o que o processo enxerga (PIDs, rede, sistema de arquivos, hostname). É como dar óculos pro container que só mostram parte da realidade.
- Cgroups (control groups): Limitam quanto cada container pode usar de CPU, memória, I/O, rede.
- 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.
# 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ção | O que faz |
|---|---|
FROM | Define a imagem base (todo Dockerfile começa com isso) |
WORKDIR | Define o diretório de trabalho dentro do container |
COPY | Copia arquivos do host para a imagem |
RUN | Executa um comando durante o build |
ENV | Define variáveis de ambiente |
EXPOSE | Documenta qual porta o container usa (não abre, só documenta) |
CMD | Comando padrão que roda quando o container inicia |
ENTRYPOINT | Similar ao CMD, mas mais "fixo" (não sobrescreve fácil) |
Comandos Docker que você usa todo dia
# 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:v1Decifrando 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