Docker: Prática Integrada da Fase 3

Última atualização: 2026-08-26

Reunindo os Conceitos da Fase 3 — Construindo um Backend de E-commerce Baseado em Microsserviços.

1. O Que Você Vai Aprender



2. A História por Trás do Backend de uma Plataforma de E-commerce

(1) Ponto de Dor: 6 serviços que precisam ser iniciados manualmente

Charlie precisa implantar seis serviços para o backend da plataforma de e-commerce: um frontend React, um proxy reverso Nginx, uma API Go, PostgreSQL, um cache Redis e uma fila de mensagens RabbitMQ. Usar docker run manualmente exige lembrar mais de 30 parâmetros e, como a ordem de inicialização é rigorosa, a taxa de erro é extremamente alta.

(2) Uma Solução para Composição com Um Clique

Charlie resolveu tudo com um único arquivo docker-compose.yml.

BASH
docker compose up -d

(3) Benefícios: Inicialização com um clique para 6 serviços

Reduzido de 30 minutos manualmente para docker compose up -d em 30 segundos. Novas contratações podem ter todo o backend em execução em 5 minutos.



3. Design da Arquitetura de Microsserviços

(1) Visão Geral da Arquitetura

100%
graph TB
    USER["Navegador"] --> NGX["Nginx<br/>:80 Proxy Reverso"]
    NGX -->|"api/"| API1["Go API #1<br/>:8080"]
    NGX -->|"api/"| API2["Go API #2<br/>:8080"]
    NGX -->|"api/"| API3["Go API #3<br/>:8080"]
    NGX -->|"/"| REACT["React SPA<br/>Arquivos Estáticos"]
    API1 --> PG["PostgreSQL<br/>:5432"]
    API2 --> PG
    API3 --> PG
    API1 --> REDIS["Redis<br/>:6379"]
    API2 --> REDIS
    API3 --> MQ["RabbitMQ<br/>:5672"]

(2) Lista de Serviços

Serviço Imagem Porta Rede Dependências
Nginx nginx:1.25-alpine 80→80 frontend, backend api (healthy)
React Auto-hospedado (multi-estágio) - frontend -
Go API Construção própria (multi-estágio) 8080 backend, db-net, cache-net postgres (healthy), redis
PostgreSQL postgres:15-alpine 5432 db-net -
Redis redis:7-alpine 6379 cache-net -
RabbitMQ rabbitmq:3-management 5672, 15672 backend -


4. Escrevendo Arquivos Compose

▶ Exemplo: Escrevendo um Arquivo compose Completo (Dificuldade: ⭐⭐⭐)

YAML
# ============================================
# docker-compose.yml - Microsserviços de e-commerce
# ============================================

services:
  # ---------- Frontend ----------
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - react-build:/usr/share/nginx/html:ro
    depends_on:
      api:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - frontend
      - backend
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 5s

  react:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    volumes:
      - react-build:/app/build
    networks:
      - frontend

  # ---------- Backend ----------
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgresql://appuser:${DB_PASSWORD:-secret}@postgres:5432/${DB_NAME:-ecommerce}
      REDIS_URL: redis://redis:6379
      RABBITMQ_URL: amqp://guest:guest@rabbitmq:5672
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    networks:
      - backend
      - db-net
      - cache-net
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 10s
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"

  # ---------- Armazenamento de Dados ----------
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}
      POSTGRES_DB: ${DB_NAME:-ecommerce}
    volumes:
      - pg-data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - db-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    restart: unless-stopped
    networks:
      - cache-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s

  rabbitmq:
    image: rabbitmq:3-management-alpine
    ports:
      - "15672:15672"   # Interface de Gerenciamento
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
    volumes:
      - mq-data:/var/lib/rabbitmq
    restart: unless-stopped
    networks:
      - backend

# ---------- Volumes ----------
volumes:
  pg-data:
  redis-data:
  mq-data:
  react-build:

# ---------- Redes ----------
networks:
  frontend:
  backend:
  db-net:
    internal: true   # Sem acesso externo
  cache-net:
    internal: true

(1) Configuração do Nginx (Balanceamento de Carga)

TEXT 📖 Somente leitura
# nginx.conf
upstream api_backend {
    server api:8080;   # DNS round-robin do Docker para 3 réplicas
}

server {
    listen 80;
    server_name localhost;

    # Arquivos estáticos (React SPA)
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    # Proxy da API
    location /api/ {
        proxy_pass http://api_backend/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}


5. Configuração Multi-Ambiente

▶ Exemplo: Sobrescrevendo no ambiente de desenvolvimento (Dificuldade: ⭐⭐)

YAML
# docker-compose.dev.yml
services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    volumes:
      - ./api/src:/app/src   # Hot-reload
    environment:
      GO_ENV: development
    deploy:
      replicas: 1            # Réplica única para depuração

  # Apenas dev: interface de administração do banco de dados
  adminer:
    image: adminer
    ports:
      - "8081:8080"
    profiles: ["dev"]
    networks:
      - db-net


6. Verificações de Saúde e Auto-Cura

▶ Exemplo: Adicionando verificações de saúde a todos os serviços (Dificuldade: ⭐⭐)

YAML
# Configuração de verificação de saúde para cada serviço
services:
  api:
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s

  postgres:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

Saída:

NAME                STATUS
ecommerce-api-1     Up 2 minutes (healthy)
ecommerce-postgres  Up 2 minutes (healthy)
ecommerce-redis-1   Up 2 minutes (healthy)


7. Verificar a Implantação

(1) Lista de Verificação

Item de Teste Comando Resultado Esperado
Todos os serviços em execução docker compose ps 6+ serviços ativos
Nginx Saudável curl http://localhost 200 OK
API Health curl http://localhost/api/health {"status":"ok"}
Número de réplicas da API docker compose ps api 3 contêineres
Conexão Redis docker compose exec redis redis-cli ping PONG
Conexão PostgreSQL docker compose exec postgres pg_isready accepting connections
Isolamento do Banco de Dados Ping no Postgres do contêiner Nginx Falhou (rede interna)


8. Exemplo Completo: Implantação com Um Clique de uma Plataforma de E-commerce

BASH
# ============================================
# Passo a passo completo: Microsserviços de e-commerce
# ============================================

# 1. Construir e iniciar todos os serviços
docker compose up -d --build

# 2. Verificar se todos os serviços estão em execução
docker compose ps

# 3. Verificar status de saúde
docker compose ps --format "table {{.Name}}\t{{.Status}}"

# 4. Testar a API
curl -s http://localhost/api/health | python3 -m json.tool

# 5. Verificar balanceamento de carga (múltiplas requisições para diferentes réplicas)
for i in $(seq 1 6); do
  curl -s http://localhost/api/health | jq -r '.hostname'
done

# 6. Verificar conectividade do banco de dados a partir da API
docker compose exec api wget -qO- http://localhost:8080/health

# 7. Acessar interface de gerenciamento do RabbitMQ
# Abra http://localhost:15672 (guest/guest)

# 8. Visualizar logs
docker compose logs -f api

# 9. Escalar API para 5 réplicas
docker compose up -d --scale api=5

# 10. Limpar
docker compose down
docker compose down -v  # Também remove volumes de dados

❓ Perguntas Frequentes

P: Devo usar aliases de rede ou nomes de serviço para comunicação entre serviços? R: No Compose, recomenda-se usar nomes de serviço (como postgres e redis). O Compose registra automaticamente registros DNS para cada serviço, e o nome do serviço serve como hostname. Aliases de rede são usados em cenários onde o mesmo serviço requer nomes diferentes em redes diferentes.

P: Como a ordem de inicialização das dependências é garantida? R: depends_on + condition: service_healthy. A API só iniciará após a verificação de saúde do postgres ser aprovada. Nota: depends_on: [db] (condição padrão: service_started) apenas aguarda o contêiner iniciar; não aguarda o serviço estar pronto.

P: Como a API de múltiplas instâncias lida com balanceamento de carga? R: DNS round-robin integrado do Docker + upstream Nginx. Todos os três contêineres da API são registrados com o nome DNS api, e o upstream api_backend { server api:8080; } do Nginx fará round-robin nas requisições. Para estratégias de balanceamento de carga mais complexas, você pode usar HAProxy.

P: Como configuro replicação mestre-escravo para um banco de dados? R: Para uma instância Compose de nó único, você pode usar vários contêineres PostgreSQL com replicação mestre-escravo configurada. No entanto, para replicação mestre-escravo de nível de produção, recomendamos usar um banco de dados gerenciado (AWS RDS / provedor de nuvem) ou ferramentas dedicadas (Patroni/Stolon). A instância PostgreSQL nesta aula é de nó único.

P: Como implemento hot reloading? R: No ambiente de desenvolvimento, monte o código fonte usando um volume (ex.: -v ./api/src:/app/src) e use uma ferramenta de hot reload (air para Go, nodemon para Node, flask --debug para Python). No ambiente de produção, não monte o código fonte; em vez disso, aplique alterações de configuração via variáveis de ambiente e reinicie usando docker compose up -d.


📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Projete uma arquitetura de múltiplos serviços para um sistema de blog (Nginx + API + DB + Cache), escreva um arquivo docker-compose.yml e inicie o sistema.
  2. Exercício Avançado (Dificuldade: ⭐⭐): Configure a API com múltiplas réplicas (replicas: 3) e balanceamento de carga Nginx, e verifique se as requisições são distribuídas entre diferentes réplicas.
  3. Desafio (Dificuldade: ⭐⭐⭐): Adicione dois conjuntos de arquivos override para dev e prod (dev: adicione Adminer e hot reload; prod: adicione limites de recursos e rotação de logs) e, em seguida, inicie cada ambiente para verificar as diferenças.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%