Docker para Desenvolvedores: Imagens, Contêineres e Compose

DevOps2026-10-06TryQuickToolBox

Você criou uma aplicação web que funciona perfeitamente na sua máquina, mas quando a implanta em um servidor ou a compartilha com um colega, ela quebra. Dependências estão faltando, versões conflitam ou variáveis de ambiente estão erradas. Esse é o clássico problema "funciona na minha máquina". O Docker resolve isso empacotando sua aplicação e suas dependências em uma unidade padronizada chamada contêiner. Neste guia, você aprenderá os conceitos centrais do Docker—imagens, contêineres e Compose—e como usá-los para otimizar seu fluxo de trabalho de desenvolvimento.

O que é Docker?

Docker é uma plataforma para construir, executar e enviar aplicações em contêineres. Um contêiner é um pacote leve, autônomo e executável que inclui tudo o que é necessário para executar um software: código, runtime, ferramentas do sistema, bibliotecas e configurações. Os contêineres isolam as aplicações umas das outras e da infraestrutura subjacente, garantindo consistência entre ambientes.

Imagens vs. Contêineres

Uma imagem é um modelo somente leitura com instruções para criar um contêiner. É como um snapshot da sua aplicação e do seu ambiente. Um contêiner é uma instância executável de uma imagem. Você pode criar, iniciar, parar, mover ou excluir contêineres usando a API ou CLI do Docker.

Pense em uma imagem como uma classe e em um contêiner como um objeto (instância) dessa classe. Você pode executar vários contêineres a partir da mesma imagem, cada um isolado dos outros.

Construindo uma Imagem com um Dockerfile

Um Dockerfile é um arquivo de texto com instruções para construir uma imagem. Aqui está um exemplo simples para uma aplicação Node.js:

# Use um runtime oficial do Node.js como imagem pai
FROM node:18-alpine

# Defina o diretório de trabalho
WORKDIR /app

# Copie package.json e package-lock.json
COPY package*.json ./

# Instale as dependências
RUN npm install

# Copie o restante do código da aplicação
COPY . .

# Exponha a porta em que a aplicação é executada
EXPOSE 3000

# Defina o comando para executar a aplicação
CMD ["node", "server.js"]

Para construir a imagem, execute:

docker build -t my-node-app .

A flag -t marca a imagem com um nome (my-node-app). O . no final especifica o contexto de build (diretório atual).

Executando Contêineres

Depois de ter uma imagem, você pode executar um contêiner:

docker run -p 3000:3000 -d my-node-app

Isso mapeia a porta 3000 no seu host para a porta 3000 no contêiner e o executa em modo detached (-d).

Comandos comuns:

Gerenciando Dados com Volumes

Contêineres são efêmeros; quando são removidos, seus dados são perdidos. Para persistir dados, use volumes. Um volume é um diretório fora do sistema de arquivos do contêiner, gerenciado pelo Docker.

docker run -v my_volume:/app/data my-node-app

Você também pode montar um diretório do host (bind mount) para desenvolvimento:

docker run -v $(pwd):/app my-node-app

Docker Compose: Aplicações Multi-Contêiner

Aplicações do mundo real geralmente exigem vários serviços: um servidor web, um banco de dados, um cache, etc. O Docker Compose permite definir e executar aplicações Docker multi-contêiner usando um arquivo YAML. Aqui está um exemplo de docker-compose.yml para uma aplicação Node.js com um banco de dados PostgreSQL:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  postgres_data:

Execute toda a stack com:

docker compose up -d

Isso constrói o serviço web, baixa a imagem do Postgres, cria uma rede e inicia ambos os contêineres. O depends_on garante que o banco de dados inicie antes do serviço web.

Para parar e remover contêineres, redes e volumes:

docker compose down -v

Boas Práticas para Docker em Desenvolvimento

Comparação: Docker vs. Máquinas Virtuais

Aspecto Contêineres Docker Máquinas Virtuais
Tempo de inicialização Segundos Minutos
Uso de recursos Leve (compartilha o kernel do SO) Pesado (SO completo por VM)
Isolamento Nível de processo Nível de hardware
Portabilidade Alta (executa em qualquer lugar que o Docker executa) Limitada pela compatibilidade do hypervisor

FAQ

Qual é a diferença entre uma imagem e um contêiner?

Uma imagem é um modelo somente leitura que define a aplicação e seu ambiente. Um contêiner é uma instância em execução de uma imagem. Você pode criar vários contêineres a partir da mesma imagem.

Quando devo usar o Docker Compose?

Use o Docker Compose quando sua aplicação consistir em vários serviços (por exemplo, servidor web, banco de dados, cache) que precisam trabalhar juntos. Ele simplifica a orquestração para desenvolvimento e testes.

Como faço para persistir dados no Docker?

Use volumes para persistir dados fora do sistema de arquivos do contêiner. Os volumes são gerenciados pelo Docker e podem ser compartilhados entre contêineres. Bind mounts também podem ser usados para montar diretórios do host.

Pronto para containerizar seu próximo projeto? Comece escrevendo um Dockerfile para uma aplicação simples, depois adicione serviços gradualmente com o Docker Compose. Para mais ferramentas de desenvolvedor, confira nosso JSON Formatter para validar e embelezar seus arquivos de configuração.