Docker
  • Introdução a Containeres e Docker
    • Introdução
    • O que é um container e suas vantanges
    • VM versus Container
    • Como funcionam os containers
    • Linux
    • Container sem Docker
      • cgroup
      • cpu.max
    • LxC
    • LxD
    • Containers versus Imagens
    • Arquitetura do Docker
    • Arquitetura do Docker mais a fundo
    • Projetos Open Source
  • Instalação do Docker
    • Linux
    • Windows
      • Docker Desktop
      • Rancher Desktop
      • WSL
    • Mac
    • Visual Studio Code
  • Primeiros Passos com Docker
    • Criação e listagem básica de um container
    • Interagindo com o container
    • Executando containers continuamente
      • nginx
      • docker container run
      • docker container run nginx
      • docker container run -d nginx
      • docker container exec
    • Como usar publish de porta
      • docker container stop
      • docker container start
      • docker container rm
      • docker container rm -f $(docker container ls -qa)
    • Containers e variáveis de ambiente
      • docker container run -e
  • Desafio
    • Desafio 01 - Banco de Dados Postgresql
    • Desafio 02 - Banco de Dados MySQL
    • Desafio 03 - Banco de Dados MongoDB
  • Executando a sua primeira aplicação em containers
    • Introdução
    • Preparando o container para a aplicação
    • Executando a aplicação
      • docker container cp
  • Primeiros Passos com Docker Images
    • Introdução
    • OverlayFS na Prática
    • Copy-on-Write
    • Formas de criar uma imagem Docker
    • Como funciona o Docker Commit
    • Docker Commit na Prática
      • docker commit
    • Entendendo melhor a sua imagem
      • docker image history
      • docker image inspect
    • Entrando mais a fundo na imagem
    • Como usar a imagem Docker no modo raiz
  • Avançando em imagens Docker com Dockerfile
    • O que é Dockerfile
    • Primeira Imagem com Dockerfile
      • docker image build
    • Como funciona a construção com Dockerfile
    • Possibilidades com Dockerfile
    • FROM
    • RUN
    • WORKDIR
    • COPY
    • ADD
    • LABEL
    • ENV
    • VOLUME
    • ARG
    • EXPOSE
    • USER
    • ENTRYPOINT
    • CMD
    • ENTRYPOINT versus CMD
    • Principais comandos com imagem
    • Imagem da aplicação com Dockerfile
    • Comparando Docker Commit com Dockerfile
  • Docker Registry
    • Introdução
    • Docker Hub
    • Sua imagem com o nome certo
    • Renomear imagens com Docker Tag
      • docker image tag
    • Enviando a sua primeira imagem para o Docker Hub
      • docker image push
      • docker image pull
  • Algumas boas práticas para construção de imagem
    • Um processo por container
    • Usar imagens confiáveis
    • Otimizar sempre a sua imagem
    • Uso inteligente das camadas
    • Dockerignore
  • Multistage Build
    • Introdução
    • Multistage build na prática
    • Target para fazer o build
      • docker image build --target
    • Imagem externa no Multistage build
    • Usar um estágio de build como base
  • Docker Volume
    • Introdução
      • docker volume
    • Bind Mount
    • Particularidades do Bind Mount
    • Bind Mount no Windows
    • Exemplo com Bind Mount
    • Docker Volume
      • docker volume create
      • docker volume inspect
      • docker volume ls
      • docker volume prune
      • docker volume rm
    • Onde ficam os arquivos do Docker volume?
    • Usando o volume no Dockerfile
    • Como fazer backup de um Docker Volume
    • Exemplo com Docker Volume
    • Storage tmpfs
    • Como criar algo funcional com o que aprendemos
  • Network
    • Introdução
    • Componentes do Docker Network
    • Rede Bridge na prática
      • docker network
      • docker network create
      • docker network inspect
      • docker network ls
      • docker network prune
      • docker network rm
    • Criando a sua rede bridge
      • docker network connect
      • docker network disconnect
    • Como funciona a rede bridge por dentro
    • Rede Host na prática
    • Rede none da prática
    • Como adicionar domínios no seu container
  • Aplicação 100% no Docker
    • Introdução
    • Criação da Imagem e Envio para o Docker Hub
    • Criação do Docker Network
    • Container do PostgreSQL
    • Container da Aplicação Web
    • Atualização da aplicação
  • Docker Compose
    • Introdução
      • docker compose
    • A evolução do docker compose
    • Criação básica de um Docker Compose
      • docker compose attach
      • docker compose build
      • docker compose config
      • docker compose cp
      • docker compose create
      • docker compose down
      • docker compose events
      • docker compose exec
      • docker compose images
      • docker compose kill
      • docker compose logs
      • docker compose ls
      • docker compose pause
      • docker compose port
      • docker compose ps
      • docker compose pull
      • docker compose push
      • docker compose restart
      • docker compose rm
      • docker compose run
      • docker compose scale
      • docker compose start
      • docker compose stats
      • docker compose stop
      • docker compose top
      • docker compose unpause
      • docker compose up
      • docker compose version
      • docker compose wait
      • docker compose watch
    • Variáveis de Ambiente
    • Volume Bind Mount
    • Docker Volume
    • Docker Network - Bridge
    • Docker Network - Host Driver e Add Host
    • Ordenando a execução dos containers
    • Compose com build de imagem
    • Como Parametrizar o Compose com Variáveis de Ambiente
    • Múltiplos Composes
    • Extends
    • Merge
    • Include
    • Profiles
    • Comandos importantes do Docker Compose
  • Troubleshooting
    • Introdução
    • Docker Info
    • Docker Events
    • Docker Logs
    • Docker Inspect
    • Docker Top
    • Docker Stats
    • Docker Exec
  • Resiliência e Gerenciamento de Recursos
    • Introdução
    • Docker Restart
      • Introdução
      • on-failure
      • unless-stopped
      • always
      • Docker Compose
    • Healthcheck
      • Introdução
      • Linha de Comando
      • Docker Compose
      • Direto na Imagem
    • Gerenciamento de Recurso
      • CPU
        • Como Gerenciar CPU
        • Prática
      • Memória
        • Como Gerenciar Memória
        • Prática
      • Docker Compose
  • Fazendo um ambiente mais seguro
    • Introdução
    • Docker Scout
      • Introdução
      • Verificação Simples de Imagem
      • Como adicionar um repositório
      • Primeira melhoria na imagem
  • BUSCA RÁPIDA
    • Referências
    • Comandos
      • docker commit
      • docker compose
      • docker container
      • docker image
      • docker network
      • docker volume
    • Dockerfile
Powered by GitBook
On this page
  • Trabalhando com Múltiplos Arquivos Docker Compose: extends, merge e include
  • Estrutura de Arquivos em Projetos Complexos
  • extends: Reutilização de Configurações de Serviços
  • Combinando Arquivos com merge
  • Simulando Inclusão com Múltiplos Arquivos
  • Estratégias Avançadas para Gerenciamento de Múltiplos Arquivos
  • Quando usar extends
  • Quando Usar merge
  • Quando Usar a Simulação de include
  • Considerações Finais: Escolhendo a Abordagem Correta
  • Conclusão
  1. Docker Compose

Múltiplos Composes

PreviousComo Parametrizar o Compose com Variáveis de AmbienteNextExtends

Last updated 8 months ago

Documentação:

Formas:

Aqui está a documentação revisada e detalhada sobre como trabalhar com múltiplos arquivos Docker Compose, considerando o uso de extends, merge e include, com a versão mais recente do Docker Compose.


Trabalhando com Múltiplos Arquivos Docker Compose: extends, merge e include

O Docker Compose permite que desenvolvedores definam e gerenciem múltiplos serviços dentro de containers. No entanto, quando se lida com projetos complexos ou múltiplos ambientes, muitas vezes é necessário dividir as definições de Compose em vários arquivos para facilitar a organização e manutenção. Além disso, existem mecanismos que permitem reutilizar configurações, como o extends, merge de arquivos e simular a inclusão de arquivos comuns. Esta documentação explora como usar essas ferramentas de forma prática e extensiva.

Estrutura de Arquivos em Projetos Complexos

Em ambientes reais, como desenvolvimento, testes e produção, é comum que existam diferentes necessidades de configuração. Manter todas essas variações em um único arquivo docker-compose.yml pode tornar o arquivo difícil de gerenciar e propenso a erros. A solução é dividir o arquivo em configurações separadas.

Exemplo de Estrutura de Arquivos:

docker-compose.yml             # Configuração principal ou base
docker-compose.override.yml     # Configurações para desenvolvimento local (sobrescrevem a base)
docker-compose.prod.yml         # Configurações para o ambiente de produção
docker-compose.test.yml         # Configurações para testes

Como Funciona:

  • Arquivo base (docker-compose.yml): Define os serviços principais que serão utilizados em todos os ambientes.

  • Arquivo de desenvolvimento (docker-compose.override.yml): Adiciona ou sobrescreve configurações para facilitar o desenvolvimento local, como mapeamento de volumes ou portas.

  • Arquivo de produção (docker-compose.prod.yml): Contém ajustes necessários para ambientes de produção, como definição de imagens específicas e estratégias de escalonamento.

  • Arquivo de testes (docker-compose.test.yml): Configurações para rodar testes automatizados ou manuais, como o uso de volumes temporários ou bancos de dados mockados.

extends: Reutilização de Configurações de Serviços

O recurso extends permite que um serviço herde a configuração de outro, seja dentro do mesmo arquivo ou de outro arquivo Compose. Isso evita a duplicação de código, facilitando a manutenção das configurações, especialmente quando há muitas similaridades entre os serviços.

Exemplo Prático:

Suponha que você tenha um serviço app que precisa ser configurado levemente diferente para desenvolvimento e produção. O arquivo base (docker-compose.yml) pode conter a definição comum, enquanto os outros arquivos estendem essa configuração com as variações necessárias.

Arquivo docker-compose.yml (base):

version: '3'
services:
  app:
    image: meuapp:latest
    environment:
      - NODE_ENV=production
    volumes:
      - ./data:/app/data
    ports:
      - "80:80"

Arquivo docker-compose.dev.yml (desenvolvimento):

version: '3'
services:
  app:
    extends:
      file: ./docker-compose.yml
      service: app
    environment:
      - NODE_ENV=development
    volumes:
      - ./src:/app/src
    ports:
      - "8080:80"

Neste exemplo:

  • O serviço app no arquivo base é configurado para produção.

  • No arquivo de desenvolvimento (docker-compose.dev.yml), a configuração é estendida a partir do arquivo base, e apenas os parâmetros específicos do ambiente de desenvolvimento, como as variáveis de ambiente e o volume mapeado, são modificados.

Esse padrão de uso de extends torna o processo de ajuste entre ambientes mais simples e modular.

Benefícios:

  • Redução de Redundância: Reutilizar configurações reduz a duplicação de código entre diferentes ambientes.

  • Manutenção Simplificada: Ajustar uma única configuração base reflete-se automaticamente nos serviços que a estendem.

Combinando Arquivos com merge

A flag -f do comando docker compose permite combinar múltiplos arquivos Compose. Ao utilizar essa funcionalidade, você pode aplicar as configurações de um arquivo e, em seguida, sobrepor ou complementar as definições com os arquivos subsequentes.

Exemplo de Uso:

Se você tiver um arquivo base docker-compose.yml e outro específico para desenvolvimento docker-compose.dev.yml, pode combiná-los ao iniciar os containers:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

Neste exemplo:

  • O Docker Compose primeiro carrega as definições do arquivo docker-compose.yml.

  • Em seguida, as configurações do arquivo docker-compose.dev.yml são aplicadas, substituindo ou complementando a configuração base.

Essa abordagem é especialmente útil para ambientes onde há pequenas diferenças nas definições, como mudanças nas variáveis de ambiente ou nos volumes. Além disso, ao combinar arquivos dessa forma, você mantém a modularidade e flexibilidade do seu ambiente de containers.

Vantagens:

  • Flexibilidade: Permite modificar ou complementar configurações de maneira seletiva.

  • Controle Fino: Cada arquivo pode tratar de configurações específicas sem alterar o comportamento global.

Simulando Inclusão com Múltiplos Arquivos

Embora o Docker Compose não tenha uma funcionalidade nativa de "inclusão" de arquivos, você pode simular essa ideia combinando arquivos que contêm partes comuns de configuração. Isso é útil, por exemplo, quando você quer compartilhar a mesma configuração de rede ou volumes entre diferentes ambientes.

Exemplo de Arquivo Comum:

Você pode criar um arquivo que contém definições que serão utilizadas em outros ambientes, como volumes e redes compartilhadas.

Arquivo common.yml:

version: '3'
services:
  db:
    image: postgres:latest
    volumes:
      - db_data:/var/lib/postgresql/data
volumes:
  db_data:

Arquivo docker-compose.prod.yml:

version: '3'
services:
  app:
    image: meuapp:prod
    depends_on:
      - db

Ao iniciar os serviços de produção, você pode combinar o arquivo common.yml com o arquivo de produção:

docker compose -f common.yml -f docker-compose.prod.yml up -d

Aqui, o arquivo common.yml define os recursos comuns, como volumes e redes, e pode ser reutilizado em diferentes ambientes. Isso proporciona uma abordagem modular e limpa para organizar configurações complexas.

Benefícios:

  • Reutilização de Definições Comuns: Recursos como volumes e redes podem ser definidos uma vez e usados em vários arquivos.

  • Organização Modular: Facilita o entendimento de grandes conjuntos de configurações.

Estratégias Avançadas para Gerenciamento de Múltiplos Arquivos

Além de usar extends e merge, você pode adotar estratégias adicionais para gerenciar múltiplos arquivos Compose:

Uso de Perfis de Configuração:

Perfis são uma maneira de ativar ou desativar certos serviços dependendo do ambiente. Eles podem ser definidos diretamente no arquivo Compose:

version: '3'
services:
  app:
    image: meuapp:latest
    profiles:
      - dev
  db:
    image: postgres:latest
    profiles:
      - prod

Ao iniciar o Compose, você pode ativar o perfil apropriado:

docker compose --profile dev up -d

Variáveis de Ambiente para Personalização Dinâmica:

Outra abordagem é usar variáveis de ambiente para adaptar um único arquivo Compose a diferentes contextos, minimizando a necessidade de arquivos adicionais.

Exemplo de arquivo docker-compose.yml:

version: '3'
services:
  app:
    image: "meuapp:${APP_ENV}"
    environment:
      - NODE_ENV=${NODE_ENV}

E no arquivo .env:

APP_ENV=development
NODE_ENV=development

Essas variáveis podem ser carregadas a partir do ambiente do sistema ou de um arquivo .env, permitindo a personalização da configuração sem alterar os arquivos Compose diretamente.

Aqui está uma explicação detalhada sobre quando utilizar cada um dos tipos abordados — extends, merge e a abordagem de simulação de include — em diferentes cenários. Vamos expandir os conceitos de forma a fornecer um entendimento profundo, sem repetir as informações específicas dos exemplos anteriores.

Quando usar extends

O extends é uma ferramenta poderosa para evitar duplicação de código e simplificar a configuração de serviços que compartilham muitas características em comum. Ele é ideal em situações onde você precisa reutilizar uma configuração base, mas com variações específicas, como diferentes ambientes ou contextos de execução.

Casos de Uso:

  1. Ambientes Comuns com Pequenas Variações: Se você tiver múltiplos ambientes, como desenvolvimento, teste e produção, e esses ambientes compartilham a maior parte das definições (imagens, variáveis de ambiente, volumes), mas têm pequenas diferenças, como portas expostas ou volumes adicionais para desenvolvimento local. O extends é perfeito para manter uma configuração central e apenas sobrepor os aspectos que variam de ambiente para ambiente.

  2. Reuso de Configuração Entre Serviços Relacionados: Em projetos onde você tem serviços que compartilham uma infraestrutura semelhante — por exemplo, múltiplas instâncias de uma aplicação que utilizam a mesma base de dados ou lógica de autenticação — você pode criar uma configuração base e estendê-la para ajustar o comportamento de cada serviço. Isso é útil em microserviços que dependem de uma configuração similar.

  3. Manutenção Simplificada: Quando você espera que a configuração dos serviços possa mudar ao longo do tempo, mas deseja evitar ter que atualizar múltiplos arquivos manualmente. Usar extends garante que uma mudança na configuração base (como atualizar a versão de uma imagem Docker) será aplicada automaticamente a todos os serviços que dependem dessa base.

Limitações:

  • Embora o extends facilite a modularização, ele pode gerar confusão em grandes equipes, especialmente quando a cadeia de herança se torna muito longa. Mantenha o uso do extends simples e evite criar dependências excessivas entre múltiplos arquivos para reduzir o risco de erros difíceis de diagnosticar.

Quando Usar merge

A estratégia de merge via o uso da flag -f no comando docker compose é altamente flexível e permite uma combinação dinâmica de múltiplos arquivos de configuração. Este método é útil em cenários onde você precisa sobrepor arquivos de configuração de forma granular, controlando como e quando as mudanças devem ser aplicadas.

Casos de Uso:

  1. Gerenciamento de Configurações Multiambiente: O merge é ideal quando você trabalha em diferentes ambientes (desenvolvimento, produção, teste) e precisa combinar arquivos de configuração específicos para cada ambiente sem criar uma duplicação desnecessária. Por exemplo, o arquivo base contém as configurações principais, e os arquivos específicos de ambiente (override, prod, test) contêm apenas as modificações. Dessa forma, ao combinar os arquivos, você pode ajustar seu ambiente conforme a necessidade.

  2. Testes Temporários ou Experimentais: Se você precisa fazer testes temporários em um ambiente sem modificar o arquivo base de configuração, o merge permite que você adicione configurações experimentais sem alterar permanentemente o ambiente. Você pode criar um arquivo de configuração específico para esses testes, rodar o Compose com a combinação dos arquivos e depois descartar as mudanças.

  3. Flexibilidade na Execução de Diferentes Cenários: Em projetos onde diferentes times podem usar a mesma infraestrutura, mas com pequenas variações de configuração, o merge permite que cada time mantenha seus próprios arquivos de configuração. Isso é útil, por exemplo, quando um time precisa de recursos de rede ou volumes adicionais, enquanto outros times podem precisar de versões diferentes de serviços sem impactar o projeto global.

  4. Controle de Ordem de Aplicação: O merge permite o controle da ordem em que as configurações são aplicadas. Como o Docker Compose carrega as definições de cada arquivo na sequência, você pode definir um arquivo base e sobrescrever as partes necessárias com arquivos subsequentes, mantendo controle total sobre quais configurações prevalecem.

Limitações:

  • O merge pode aumentar a complexidade se utilizado em excesso, criando dependências difíceis de gerenciar entre múltiplos arquivos. Se houver muitas camadas de sobreposição, a configuração final pode se tornar difícil de interpretar.

Quando Usar a Simulação de include

Simular a inclusão de arquivos comuns através do uso de múltiplos arquivos é uma abordagem recomendada quando há partes da configuração que precisam ser reutilizadas em vários contextos, mas sem que os serviços individuais sejam estendidos diretamente. Ao invés de criar uma estrutura hierárquica de dependências, como no extends, você está basicamente “importando” blocos de configuração comuns em diferentes arquivos.

Casos de Uso:

  1. Reuso de Definições de Recursos Compartilhados: Se você tem volumes, redes ou serviços de infraestrutura (como bancos de dados) que são usados por múltiplos ambientes ou serviços, criar um arquivo de configuração comum para essas definições pode evitar redundância. Essa abordagem é especialmente útil quando esses recursos são compartilhados entre diferentes serviços que não precisam herdar suas configurações diretamente, mas dependem de sua existência.

  2. Manutenção de Configurações Compartilhadas em Projetos Multi-Equipe: Em projetos onde várias equipes estão trabalhando em diferentes componentes ou microserviços, mas todos compartilham certas partes da infraestrutura (como redes internas, bancos de dados, ou sistemas de cache), o uso de arquivos comuns permite que cada equipe mantenha sua configuração separada, mas sem duplicar a definição desses recursos.

  3. Segregação de Componentes Complexos: Em arquiteturas mais complexas, onde diferentes serviços têm dependências comuns, como bancos de dados, redes e volumes, a simulação de include pode ser usada para separar essas definições de forma clara e reutilizá-las em diversos contextos. Isso garante que, mesmo que a arquitetura cresça e novos serviços sejam adicionados, você não precise redefinir recursos básicos a cada novo arquivo de configuração.

  4. Facilidade na Escalabilidade de Projetos: À medida que o projeto cresce e novos serviços ou ambientes são adicionados, a abordagem de include facilita a introdução de novos serviços sem a necessidade de copiar ou duplicar definições de configuração. Com arquivos comuns, você simplesmente "inclui" as configurações compartilhadas, mantendo a flexibilidade para ajustar o restante conforme necessário.

Limitações:

  • Simular o include exige cuidado para que as configurações comuns sejam realmente reutilizáveis e não causem conflitos em diferentes ambientes. O gerenciamento de muitos arquivos comuns pode se tornar complicado se não houver uma estratégia clara de organização.

Considerações Finais: Escolhendo a Abordagem Correta

  • Se você precisa ajustar levemente uma configuração base para diferentes ambientes ou serviços, use extends. Ele permite que você evite duplicação e mantenha a consistência das configurações com pequenas variações.

  • Se você precisa combinar arquivos de configuração de forma flexível, ajustando diferentes cenários sob demanda, o merge é a abordagem mais adequada. Ele proporciona flexibilidade sem forçar uma hierarquia de dependências entre os serviços.

  • Se você deseja manter recursos compartilhados em um arquivo separado e reutilizá-los em múltiplos arquivos sem criar relações diretas entre os serviços, a simulação de include é a melhor opção. Isso é particularmente útil quando as definições de infraestrutura são comuns a todos os ambientes, mas não precisam ser ajustadas diretamente por cada serviço.

Ao compreender profundamente cada uma dessas abordagens, você pode adaptar sua arquitetura Docker Compose para que ela seja eficiente, modular e fácil de manter, garantindo que seu ambiente de containers seja escalável e flexível para o futuro.

Conclusão

A utilização de múltiplos arquivos Docker Compose, combinada com as funcionalidades de extends, merge e uma abordagem simulada de include, oferece uma maneira poderosa de gerenciar configurações de containers em ambientes complexos. Essas técnicas permitem modularizar as definições, reduzir a duplicação e facilitar a manutenção de grandes projetos. Ao adotar essas práticas, você garante que seus ambientes sejam flexíveis, reutilizáveis e fáceis de escalar, facilitando o desenvolvimento, testes e a operação em produção.


Essa documentação foi expandida para cobrir os conceitos em profundidade, explicando as funcionalidades com exemplos práticos e detalhados para facilitar a compreensão.

Merge
Include
Extends
OverviewDocker Documentation
Logo