Marcio Cunha

Como gerenciar múltiplos ambientes Docker com Compose profiles

Aprenda a isolar serviços de desenvolvimento e produção usando Docker Compose profiles para otimizar os recursos do seu servidor ou computador local.

Marcio Cunha•5 min
Também disponível em:EnglishEspañol
Resumo
  • Profiles evitam a execução simultânea desnecessária de bancos pesados no notebook.
  • A divisão por tags lógico-funcionais simplifica pipelines de integração contínua.
  • O uso do parâmetro --profile permite subir apenas o que é exigido no momento.
  • Variáveis de ambiente isoladas garantem segurança entre homologação e produção.
  • O gerenciamento de portas conflituosas torna-se trivial com a ativação seletiva.

Por que o isolamento de ambientes é um desafio local?

Quando desenvolvemos software moderno, é comum precisarmos de uma pilha completa de serviços rodando na máquina local: bancos de dados, filas de mensagens, caches e ferramentas de monitoramento. No entanto, deixar tudo ligado ao mesmo tempo consome muita memória RAM e processamento, o que costuma deixar o computador lento. Na prática, isso significa que a sua máquina sofre para rodar compiladores enquanto o Docker mantém três instâncias de banco ociosas em segundo plano.

Para contornar esse desperdício de recursos de infraestrutura, muitos engenheiros recorrem a múltiplos arquivos de configuração separados ou scripts complexos de shell. O problema é que essas abordagens geram manutenção duplicada e confusão na hora de subir o sistema. É exatamente nesse cenário que entram os profiles do Docker Compose, permitindo agrupar serviços em categorias lógicas sem precisar duplicar o código base de infraestrutura.

O que são e como funcionam os profiles no Docker Compose?

Um profile, ou perfil de execução, é um rótulo que você atribui a determinados blocos de serviços dentro do seu arquivo YAML. Quando você executa o comando padrão para subir a aplicação, o Docker ignora qualquer serviço que possua um profile associado, a menos que você solicite expressamente a ativação daquele grupo. Na prática, isso funciona como um filtro inteligente que decide quais peças do quebra-cabeça devem ser montadas.

Imagine que você tem uma ferramenta essencial de monitoramento ou um painel de administração como o Portainer ou o Dozzle para acompanhar os logs. Esses utilitários são úteis no dia a dia de desenvolvimento, mas totalmente desnecessários quando você está rodando apenas testes automatizados em um servidor de integração contínua. Ao associar esses utilitários a um perfil específico, você garante que eles só apareçam quando forem chamados, mantendo o ambiente limpo.

Inclusive, para quem gerencia servidores dedicados ou homelabs, manter a segurança da rede é tão importante quanto economizar recursos. Em artigos anteriores, já discutimos como bloquear varreduras de portas e brute-force com iptables para proteger os serviços expostos. Com os profiles, você reduz ainda mais a superfície de ataque ao garantir que bancos de dados de teste ou ferramentas administrativas fiquem completamente desligados por padrão.

Estruturando um arquivo Docker Compose com múltiplos perfis

Vamos colocar a mão na massa criando uma estrutura realista onde separamos o banco de dados principal, uma ferramenta de cache e um serviço auxiliar de visualização de logs. A ideia central é que o desenvolvedor consiga rodar apenas a aplicação essencial, enquanto o banco de dados e as ferramentas de suporte são acionados apenas sob demanda. Veja abaixo como estruturar esse arquivo de configuração de forma limpa e organizada.

version: '3.8'

services:
  app:
    image: my-web-app:latest
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development

  database:
    image: postgres:15-alpine
    profiles: ["infra"]
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

  adminer:
    image: adminer:latest
    profiles: ["tools"]
    ports:
      - "8080:8080"

volumes:
  pgdata:

No exemplo acima, note que os serviços database e adminer possuem a chave profiles definida. Se você rodar apenas o comando básico de inicialização, apenas o serviço web principal será iniciado. Isso evita que sua máquina fique travada tentando subir o banco de dados inteiro quando você quer apenas testar um ajuste visual simples no código fonte.

Como acionar e alternar perfis na linha de comando

Para colocar os serviços adicionais para funcionar, você precisa informar explicitamente quais perfis deseja ativar durante a execução do comando Compose. Isso é feito utilizando a flag correspondente acompanhada do nome do grupo que definimos no arquivo YAML. Na prática, isso significa que o controle total do ciclo de vida dos recursos fica na ponta dos seus dedos, sem scripts malabaristas.

  1. Abra o terminal na pasta raiz onde está o seu arquivo de configuração do Docker Compose.
  2. Execute o comando abaixo para iniciar apenas o aplicativo web junto com o banco de dados configurado no perfil infra.
  3. Valide se todos os containers esperados estão rodando corretamente através da listagem padrão de processos.
docker compose --profile infra up -d

Caso você queira subir tanto o banco de dados quanto as ferramentas administrativas de uma só vez, basta passar múltiplos parâmetros de perfil na mesma linha de comando. Na prática, isso se traduz em escrever docker compose --profile infra --profile tools up -d. Esse nível de flexibilidade é excelente para simular ambientes complexos na própria máquina antes de enviar o código para produção.

Cuidados essenciais com volumes persistentes e portas

Um erro muito comum ao isolar serviços utilizando profiles é esquecer que volumes de dados continuam ocupando espaço em disco mesmo quando os containers associados estão parados. Se você altera frequentemente os perfis de execução, vale a pena conhecer técnicas complementares de limpeza, como as que abordamos em como limpar o cache do Docker e recuperar espaço em disco para evitar surpresas desagradáveis com o armazenamento esgotado.

Outro ponto crítico envolve o mapeamento de portas de rede. Como diferentes perfis podem tentar utilizar a mesma porta física da sua máquina para serviços similares — por exemplo, um banco MySQL de testes e outro de homologação —, planejar as portas ou delegar redes internas customizadas evita conflitos catastróficos. Garantir que cada ambiente ocupe seu próprio espaço lógico é o segredo para uma operação sem atritos.

Considerações finais

O uso inteligente de Docker Compose profiles transforma a maneira como lidamos com a infraestrutura local e os pipelines de entrega contínua. Ao abandonar a velha prática de acumular dezenas de containers desnecessários rodando em segundo plano, ganhamos velocidade, estabilidade e uma economia preciosa de recursos computacionais. Integrar essa estratégia no seu fluxo diário de desenvolvimento garante que o foco volte a ser o código, e não a luta contra travamentos na máquina.