Docker Compose em Produção: Tutorial Passo a Passo para Times de TI

16/10/2026  ·  Devskin

Docker Compose em Produção: Tutorial Passo a Passo para Times de TI

Usar docker compose em produção é uma decisão legítima para muitos times de TI, desde que você conheça os limites da ferramenta e aplique um mínimo de disciplina operacional. Neste tutorial, você vai montar uma stack com aplicação e PostgreSQL, adicionar healthchecks, proteger segredos, executar deploys repetíveis e preparar backup. O foco é um único host Linux, o cenário em que o Compose entrega mais valor com menos complexidade.

Quando faz sentido usar Docker Compose em produção

O Compose descreve serviços, redes e volumes em um arquivo declarativo e delega a execução ao Docker Engine. Não existe scheduler multi-nó, autoscaling nativo nem reconciliação contínua como no Kubernetes. Por isso, avalie os trade-offs antes de decidir.

  • Vantagens: baixa curva de aprendizado, configuração versionável no Git, paridade entre desenvolvimento e produção, baixo overhead de recursos.
  • Desvantagens: ponto único de falha no host, escala horizontal manual, rolling update limitado e sem self-healing além da política de restart.
  • Casos de uso concretos: SaaS em estágio inicial, ferramentas internas, ambientes de homologação, painéis de monitoramento e serviços de clientes com carga previsível.

Se você ainda não automatizou a entrega, veja também o Deploy Automatizado com GitHub Actions e Docker: Tutorial Passo a Passo, que complementa este guia no pipeline de CI/CD.

Passo 1: estruture o projeto

Mantenha tudo em um diretório dedicado no servidor, versionado em um repositório de infraestrutura:

  • compose.yaml: definição dos serviços.
  • .env: variáveis não sensíveis, como tags de imagem e portas.
  • secrets/: arquivos de segredo, fora do Git e com permissão restrita (chmod 600).
  • backups/: destino temporário de dumps antes do envio para storage externo.

Passo 2: escreva o compose.yaml pensando em produção

O exemplo abaixo usa imagem com tag fixa, política de restart, rede interna, volume nomeado e segredo via arquivo. Evite a tag latest: ela torna o deploy não determinístico e dificulta o rollback.

services:
  app:
    image: ghcr.io/sua-org/app:1.4.2
    restart: unless-stopped
    env_file: .env
    mem_limit: 512m
    depends_on:
      db:
        condition: service_healthy
    ports:
      - 127.0.0.1:8080:8080
    healthcheck:
      test: [CMD-SHELL, wget -qO- http://localhost:8080/health || exit 1]
      interval: 15s
      timeout: 5s
      retries: 3
    networks: [backend]
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: app
      POSTGRES_DB: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: [CMD-SHELL, pg_isready -U app -d app]
      interval: 10s
      timeout: 5s
      retries: 5
    networks: [backend]
volumes:
  pgdata:
networks:
  backend:
secrets:
  db_password:
    file: ./secrets/db_password.txt

Pontos de atenção neste arquivo de Docker Compose: a porta da aplicação é publicada apenas em 127.0.0.1, para que um reverse proxy (Nginx, Caddy ou Traefik) faça a terminação TLS; o banco não expõe porta alguma; e o healthcheck do wget pressupõe que a imagem tenha esse binário, então adapte conforme a sua base.

Passo 3: healthchecks e ordem de inicialização

A diretiva depends_on sozinha só garante a ordem de criação dos containers, não a prontidão do serviço. Com condition: service_healthy, o docker compose aguarda o healthcheck do PostgreSQL passar antes de iniciar a aplicação. Isso evita falhas de conexão no boot, mas não substitui retry com backoff no código: o banco pode cair depois da inicialização.

Passo 4: segredos e variáveis de ambiente

  • Prefira segredos em arquivo (_FILE, quando a imagem suporta) em vez de variáveis de ambiente, que aparecem em docker inspect.
  • Nunca versione o .env com credenciais; mantenha um .env.example com valores fictícios.
  • Valide a configuração final com docker compose config, que mostra o YAML já interpolado e acusa erros de sintaxe.

Os segredos de arquivo do Compose são montados em /run/secrets, mas, fora do Swarm, são um bind mount com as permissões do arquivo de origem. Trate-os como proteção contra vazamento acidental, não como cofre. Para exigências maiores, integre um gerenciador de segredos externo.

Passo 5: deploy repetível e rollback

Um deploy simples e previsível segue três comandos:

docker compose pull
docker compose up -d --remove-orphans
docker compose ps

O up -d recria apenas os serviços cuja imagem ou configuração mudou. Há uma breve indisponibilidade da aplicação durante a troca do container; se isso for inaceitável, use um proxy com dois upstreams e alterne entre eles (estratégia blue/green manual) ou considere um orquestrador. Para rollback, basta voltar a tag anterior no .env e repetir o up -d, motivo pelo qual as tags imutáveis são essenciais. Automatize esse fluxo no pipeline e registre o commit e a tag de cada release.

Passo 6: backup, logs e observabilidade

Volumes nomeados persistem dados, mas não são backup. Agende um dump lógico com pg_dump via cron ou timer do systemd, envie o arquivo para um storage externo e teste a restauração periodicamente. Um backup nunca restaurado é apenas uma hipótese.

Quanto aos logs, o driver padrão json-file cresce sem limite. Configure rotação por serviço com logging.options (max-size e max-file) ou envie a saída para um coletor central. Para métricas, adicione cAdvisor e um exporter do PostgreSQL ao docker compose, ou use o Prometheus que você já opera. Se a preocupação é custo de infraestrutura, o artigo Custo de Cloud: como reduzir até 70% com DevOps na prática mostra como combinar visibilidade e rightsizing.

Limites que você precisa respeitar

  • Alta disponibilidade: um host significa um ponto único de falha. Mitigue com snapshots, backups e automação para recriar o servidor.
  • Escala: aumentar réplicas com --scale funciona, mas exige balanceamento e cuidado com portas e estado.
  • Segurança: mantenha o Docker Engine atualizado, evite containers privilegiados e rode processos como usuário não root.
  • Crescimento: quando precisar de múltiplos nós, rolling updates reais e autoscaling, migre para Kubernetes ou outro orquestrador. O arquivo Compose serve como base para essa conversão.

Conclusão

O Docker Compose em produção funciona bem quando você fixa versões, usa healthchecks, protege segredos, automatiza o deploy e testa backups. Ele não resolve alta disponibilidade, mas entrega um caminho simples, auditável e barato para equipes que querem previsibilidade. Comece pela stack deste tutorial, meça o comportamento real e só adicione complexidade quando a carga ou o SLA exigirem.

Contato

Envie uma mensagem

Entre em contato