1. Retomando: de imagens a containers em execução
Na primeira parte desta série vimos o que é o Docker, o problema que ele resolve e os três conceitos fundamentais — imagens, containers e registries. Agora que a base teórica está posta, o foco deste artigo é prático: os comandos que efetivamente viram hábito no uso diário — run, exec, logs, ps, build — aplicados a containers reais, não só ao hello-world.
2. docker run além do básico
O artigo anterior já usou docker run para subir um Nginx. Vale conhecer as flags que aparecem o tempo todo:
# Modo interativo, útil para explorar uma imagem manualmente
docker run -it ubuntu bash
# Variáveis de ambiente
docker run -e POSTGRES_PASSWORD=segredo -d postgres
# Montar um diretório do host dentro do container (volume bind mount)
docker run -v $(pwd)/dados:/dados -d minha-imagem
# Remover o container automaticamente quando ele parar
docker run --rm -it python:3.12 python3
# Limitar recursos
docker run --memory=512m --cpus=1 minha-imagem
-
-itcombina-i(interativo, mantém STDIN aberto) com-t(aloca um pseudo-terminal) — é o par de flags para "entrar" em um container e usar um shell como se fosse uma máquina normal. -
--rmevita acumular containers parados no disco depois de testes rápidos e descartáveis — sem ela, cadadocker rundeixa um container parado para trás até ser removido manualmente. -
-edefine variáveis de ambiente; imagens oficiais como a do Postgres costumam documentar quais variáveis elas esperam (usuário, senha, nome do banco inicial).
3. Inspecionando o que está rodando
O comando mais usado para ter uma visão geral do que o Docker está gerenciando na máquina:
docker ps # containers em execução
docker ps -a # todos, incluindo parados
docker ps -q # só os ids (útil em scripts)
Para investigar um container específico mais a fundo:
docker inspect meu-container # todos os metadados em JSON: rede, volumes, config
docker top meu-container # processos rodando dentro do container
docker stats # uso de CPU/memória em tempo real de todos os containers
docker stats é particularmente útil para detectar um container consumindo memória ou CPU muito acima do esperado, sem precisar entrar nele.
4. Logs: a primeira ferramenta de debug
Containers geralmente não têm um arquivo de log tradicional acessível de fora — a convenção do Docker é que a aplicação escreva na saída padrão (stdout/stderr), e o Docker captura isso automaticamente:
docker logs meu-container # todo o log acumulado
docker logs -f meu-container # segue o log em tempo real (como tail -f)
docker logs --tail 100 meu-container # só as últimas 100 linhas
docker logs --since 10m meu-container # só os últimos 10 minutos
Na prática, docker logs -f nome-do-container costuma ser o primeiro comando rodado ao investigar um container que não está se comportando como esperado — antes até de entrar nele.
5. docker exec: entrando em um container já rodando
Diferente de docker run (que cria um novo container), docker exec executa um comando dentro de um container que já está rodando:
# Abrir um shell dentro de um container em execução
docker exec -it meu-container bash
# Rodar um comando pontual sem abrir shell interativo
docker exec meu-container ls /app
# Útil para inspecionar o banco de um container Postgres
docker exec -it meu-postgres psql -U postgres
Esse é o comando do dia a dia para depurar um container em produção (ou em homologação) sem reiniciá-lo: verificar se um arquivo de configuração chegou certo, olhar o conteúdo de um diretório, testar conectividade de rede com curl de dentro do container, etc.
6. docker build: da aplicação à imagem
Todos os exemplos até aqui usaram imagens prontas do Docker Hub. Para empacotar uma aplicação própria, o ponto de partida é um Dockerfile (o Artigo 3 desta série é inteiramente dedicado a escrevê-los bem) — por agora, um exemplo mínimo para uma aplicação Python:
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
Construir a imagem a partir desse arquivo:
docker build -t minha-app:1.0 .
-
-t minha-app:1.0— dá um nome (minha-app) e uma tag (1.0) à imagem resultante. Sem tag explícita, o Docker usalatestpor padrão — algo a evitar em ambientes reais, porquelatestnão diz nada sobre qual versão do código está de fato empacotada ali. -
.— o contexto de build: o diretório cujo conteúdo fica disponível para os comandosCOPY/ADDdo Dockerfile. Tudo dentro dele é enviado ao Docker daemon antes do build começar, então diretórios grandes e irrelevantes (como.git,node_modules) devem ser excluídos com um arquivo.dockerignore.
Depois de construída, a imagem já pode ser rodada como qualquer outra:
docker run -d --name minha-app-container minha-app:1.0
7. Limpando o ambiente
Containers parados, imagens não usadas e volumes órfãos se acumulam rápido durante o desenvolvimento. Comandos úteis de limpeza:
docker container prune # remove todos os containers parados
docker image prune # remove imagens "dangling" (sem tag, órfãs de build)
docker image prune -a # remove também imagens não usadas por nenhum container
docker system prune # limpeza geral: containers parados, redes e imagens não usadas
Vale rodar docker system df antes, para ter uma ideia de quanto espaço em disco está sendo ocupado por cada categoria (imagens, containers, volumes, cache de build) antes de decidir o que limpar.
8. Conclusão e próximos passos
Com run, ps, logs, exec e build, já é possível cobrir o ciclo completo do dia a dia: subir containers, inspecionar o que está rodando, depurar problemas e empacotar uma aplicação própria em imagem. No próximo artigo, o foco entra a fundo no Dockerfile: como as camadas funcionam, como aproveitar o cache de build para acelerar builds repetidos, e boas práticas para escrever um Dockerfile enxuto e eficiente.
Imagem de capa: Logo oficial do Docker — Wikimedia Commons, fonte: docker.com/company/newsroom/media-resources
Referências:
Top comments (0)