Docker para Desenvolvedores: Imagens, Contêineres e Compose
Você é desenvolvedor e já ouviu falar do Docker. Talvez já tenha tentado, mas os conceitos de imagens, contêineres e Compose parecem confusos. Ou você está cansado do "funciona na minha máquina" e quer um ambiente consistente. Este guia elimina o ruído e oferece uma compreensão prática dos componentes centrais do Docker e de como usá-los de forma eficaz.
Por que usar Docker como desenvolvedor?
O Docker resolve a inconsistência de ambientes. Em vez de instalar dependências diretamente na sua máquina, você empacota sua aplicação e suas dependências em um contêiner. Os contêineres são executados da mesma forma em todos os lugares: no seu laptop, no laptop do seu colega e em produção. Isso elimina divergências de configuração e torna o onboarding trivial.
Imagens: O Modelo
Uma imagem é um modelo somente leitura. Ela contém o código da sua aplicação, runtime, bibliotecas e variáveis de ambiente. Você cria imagens a partir de um Dockerfile, um arquivo de texto com instruções.
Aqui está um Dockerfile simples para uma aplicação Node.js:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Cada instrução cria uma camada. As camadas são armazenadas em cache, então as reconstruções são rápidas quando apenas o código muda. As imagens são armazenadas em registries como o Docker Hub ou um registry privado.
Contêineres: A Instância em Execução
Um contêiner é uma instância executável de uma imagem. Ele é isolado, mas compartilha o kernel do sistema operacional host, o que o torna leve. Você inicia um contêiner com docker run.
docker run -p 3000:3000 -d my-app
Isso mapeia a porta 3000 no host para a porta 3000 no contêiner e o executa em modo detached. Os contêineres são efêmeros: as alterações são perdidas quando removidos, a menos que você use volumes.
Comandos principais:
docker ps– lista contêineres em execuçãodocker stop <container>– para um contêinerdocker rm <container>– remove um contêinerdocker images– lista imagensdocker rmi <image>– remove uma imagem
Docker Compose: Aplicações Multi-Contêiner
Aplicações reais frequentemente precisam de múltiplos serviços: um servidor web, um banco de dados, um cache. O Docker Compose permite definir e executar aplicações multi-contêiner com um único arquivo YAML.
Aqui está um docker-compose.yml para uma aplicação Node.js com PostgreSQL:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Execute docker compose up para iniciar ambos os serviços. O Compose gerencia a rede, então o web pode acessar o db pelo nome do serviço.
Quando usar Docker Compose vs. Docker puro
| Cenário | Use |
|---|---|
| Contêiner único | docker run |
| Múltiplos serviços (app + DB) | Docker Compose |
| Orquestração em produção | Kubernetes, Swarm |
Melhores práticas para desenvolvedores
- Use .dockerignore para excluir node_modules, .git, etc., acelerando as builds.
- Builds multi-stage para manter as imagens finais pequenas.
- Fixe versões nas instruções FROM para reprodutibilidade.
- Não execute como root em contêineres de produção.
- Use volumes para dados persistentes e para recarregamento de código ao vivo durante o desenvolvimento.
Armadilhas comuns
Conflitos de porta: Se a porta 3000 estiver ocupada, mapeie para uma porta host diferente: -p 3001:3000.
Perda de dados: Sem volumes, os dados do banco de dados desaparecem quando o contêiner é removido.
Builds lentas: Ordene as instruções do Dockerfile da menos para a mais frequentemente alterada para aproveitar o cache.
FAQ
Qual é a diferença entre uma imagem e um contêiner?
Uma imagem é um modelo somente leitura; um contêiner é uma instância em execução dessa imagem. Você pode executar múltiplos contêineres a partir da mesma imagem.
Preciso do Docker Compose para um único serviço?
Não. O Compose se destaca quando você tem múltiplos serviços. Para um único contêiner, docker run é mais simples.
Como persistir dados no Docker?
Use volumes. Defina um volume nomeado no Compose ou use -v com docker run para montar um diretório host ou volume nomeado.
Pronto para otimizar seu fluxo de trabalho com Docker? Confira nosso JSON Formatter para validar e formatar rapidamente arquivos de configuração JSON como docker-compose.yml ou package.json.