Tutorial completo do Docker Compose para orquestrar contêineres.

Última atualização: 17/12/2025
autor: Isaac
  • O Docker Compose permite definir e gerenciar vários contêineres a partir de um único arquivo YAML, facilitando o trabalho com aplicações baseadas em microsserviços.
  • A seção de serviços é obrigatória e deve ser preenchida com redes, volumes, configurações e segredos para controlar a comunicação, a persistência e a configuração.
  • Exemplos como Flask+Redis ou um aplicativo full stack com frontend, backend e banco de dados mostram como o Compose simplifica o desenvolvimento e a implantação.
  • Os comandos docker compose up, down, ps e toras Eles constituem o fluxo de trabalho básico para iniciar, depurar e parar conjuntos de contêineres.

Tutorial passo a passo do Docker Compose

Se você já experimentou com contêineres e percebeu que para um aplicativo "real" você precisa Mais de um serviço em execução simultaneamente. (Banco de dados, API, frontend, cache…), mais cedo ou mais tarde você vai se deparar com o Docker Compose. Essa ferramenta permite configurar toda essa infraestrutura com um único arquivo e alguns comandos, sem precisar ficar alternando entre terminais e scripts intermináveis.

Neste tutorial, você aprenderá o que é o Docker Compose e como seu arquivo funciona. compose.yaml e como orquestrar aplicações Configurações limpas com múltiplos contêineres: desde exemplos simples com Flask e Redis até arquiteturas mais complexas com frontend, backend e banco de dados. Você também aprenderá sobre redes, volumes, configurações, segredos e os principais comandos para trabalhar confortavelmente em ambientes de desenvolvimento e mais exigentes.

O que é o Docker Compose e por que vale a pena usá-lo?

Docker Compose é uma extensão do Docker que permite Definir e gerenciar vários contêineres como se fossem uma única aplicação. Em vez de iniciar cada serviço manualmente com seu "docker run" e parâmetros, você descreve tudo em um arquivo YAML e inicia com um único comando.

A beleza do Compose reside no fato de que muitos aplicativos modernos são construídos com base nele. microsserviços que residem em contêineres individuaisUm banco de dados, uma API, um frontend, um sistema de filas, um cache tipo Redis, etc. O Docker recomenda que cada contêiner execute um único serviço; portanto, se você tentar incluir tudo em uma única imagem, acabará com um monstro difícil de escalar e manter.

Você pode executar dois ou mais serviços dentro do mesmo contêiner, mas Isso anula muitas das vantagens do Docker.Se uma parte falhar, as outras também falham; não é possível dimensionar apenas a parte que recebe a maior carga, e o gerenciamento de logs, recursos e falhas se torna uma grande bagunça.

Com o Docker Compose, você define cada serviço separadamente, especificando como eles se conectam entre si, quais dados eles armazenam, quais portas eles expõem, quais variáveis ​​de ambiente eles usam… Dessa forma Se um contêiner falhar, os demais podem continuar funcionando. Dependendo da configuração, dimensionar uma peça específica é tão simples quanto modificar suas configurações ou o número de réplicas.

Além disso, o Compose se encaixa perfeitamente nos fluxos de trabalho de CI/CD e implantação em produçãoVocê pode usá-lo diretamente com ferramentas como Portainer ou Docker Swarm e, se você trabalha com Kubernetes, projetos como o Kompose permitem traduzir um arquivo compose.yaml em manifestos do Kubernetes sem precisar reescrever tudo manualmente.

Configurando serviços com o Docker Compose

Pré-requisitos para seguir o tutorial do Docker Compose

Para acompanhar os exemplos deste tutorial com tranquilidade, você precisa Tenho o Docker e o Docker Compose instalados.Hoje existem dois caminhos principais:

  • Docker Engine + Docker Compose Instalados como binários independentes.
  • Área de trabalho do Docker, que inclui o Docker Engine, o Docker Compose e uma interface gráfica.

É importante que você tenha uma base mínima de comandos básicos do Docker (imagens, contêineres, portas, volumes) e não tenha medo de usar a linha de comando. Os exemplos geralmente pressupõem conhecimento prévio em Linux (por exemplo, Ubuntu 22.04), mas a lógica se aplica igualmente em Windows e macOS com Docker Desktop.

Verifique se tudo está em ordem executando o programa no seu computador. terminal algo tão simples quanto “docker –version” e “docker compose version”Se ambos os comandos responderem sem erros, você estará pronto para continuar com os exemplos.

Estrutura básica de um arquivo compose.yaml

O coração do Docker Compose é o arquivo compose.yaml (ou docker-compose.yml)Ali descrevemos quais serviços queremos configurar e como eles devem estar relacionados. Embora anteriormente o campo fosse usado version Para indicar a versão do formato, a documentação atual recomenda não defini-la, para que a versão mais recente do esquema seja sempre utilizada.

No arquivo Compose, você encontrará várias seções possíveis, embora apenas uma seja obrigatória: ServiçosA partir daí, você pode adicionar outras seções dependendo da complexidade do seu projeto:

  • ServiçosDefinição de cada microsserviço (obrigatório).
  • redesRedes personalizadas para controlar a comunicação entre contêineres.
  • volumes: volumes para armazenar dados ou compartilhá-los entre serviços.
  • configsConfiguração de serviço (por exemplo, arquivos de configuração do servidor web).
  • segredos!: gerenciamento de informações sensíveis (senhas, chaves de API…).

Ao longo deste tutorial, você verá como combinar todas essas seções para um projeto típico que inclui um aplicação, um banco de dados e uma APIe também um exemplo de um aplicativo web em Python Com Flask e Redis.

Serviços no Docker Compose: o núcleo da definição

A seção Os serviços são a peça essencial. a partir de qualquer arquivo Compose. Nele, você define cada um dos contêineres que comporão seu aplicativo, dando a eles o nome que desejar (por exemplo, web, database, api, redis, Etc.)

Para cada serviço, você pode estabelecer um bom número de ParâmetrosEntre elas, algumas são amplamente utilizadas em projetos do mundo real:

Parâmetro build indica onde o Dockerfile está localizado a partir da qual a imagem do serviço será construída. Normalmente, especifica-se um contexto (diretório) onde reside o Dockerfile da aplicação que você deseja empacotar.

Se você já tiver uma imagem criada ou quiser usar uma do registro, você usa image para fazer referência a issoO nome segue o formato [<registry>/][<project>/]<image>[:<tag>|@<digest>]E se você precisar controlar quando essa imagem é baixada ou atualizada, você pode usar pull_policy.

Campo ports É utilizado para mapear portas entre o host e o contêiner.A sintaxe é do tipo [HOST:]CONTAINER[/PROTOCOL]Por exemplo, se um banco de dados PostgreSQL estiver escutando na porta 5432 dentro do contêiner e você quiser expô-lo na porta 5555 do host, você faria algo assim: "5555:5432" na lista de portos.

  Guia completo sobre chave SysRq no Linux

A política de reinicialização é controlada por restartque indica o que fazer quando um contêiner termina com erro ou para. Os valores típicos são no, always, on-failure y unless-stoppedpermitindo que serviços críticos permaneçam operacionais mesmo que sofram interrupções ocasionais.

Se um serviço precisar que outro esteja disponível antes de começar, você pode usar depends_on definir dependências entre contêineresUm exemplo clássico é um aplicativo que exige que o banco de dados esteja em funcionamento para evitar falhas na conexão inicial.

Para configuração e credenciais, você tem duas abordagens comuns: env_file y environment. com env_file Você está apontando para um ou mais arquivos. .env com as variáveis ​​de ambiente, enquanto em environment Você pode listá-los diretamente no YAML. A melhor prática é usar arquivos. .env Para evitar que senhas e dados sensíveis sejam incorporados no próprio arquivo compose.yaml.

Parâmetro volumes Permite montar caminhos ou volumes do host. Dentro do contêiner, você usará tanto a persistência de dados quanto o compartilhamento de pastas entre os serviços. Aqui, você fará referência apenas aos volumes que poderá definir posteriormente na seção acima. volumes Se você precisar que elas sejam compartilhadas ou gerenciadas de forma mais explícita.

Com esses campos, você já pode criar serviços bastante completos. A especificação Compose inclui muitas outras opções avançadas (saúde, limites de recursos, comandos de Botaetc.), mas com estes você já cobre a maioria dos usos comuns.

Exemplo 1: Aplicação web em Python com Flask e Redis

Um exemplo típico para entender o Docker Compose é a criação de um aplicação web simples em PythonUtilizando Flask para servir páginas e Redis como armazenamento em memória para um contador de acessos. A ideia é que você não precise instalar Python ou Redis na sua máquina: tudo roda dentro de contêineres.

O fluxo de trabalho seria algo assim: primeiro você cria um diretório para o projeto e dentro dele adiciona um arquivo. app.py com o código Flask. Nesse código você usa "redis" como nome do host e porta 6379, que é a porta padrão para o serviço Redis no seu contêiner.

A função que gerencia o contador de visitantes. Ele tenta se conectar ao Redis várias vezes. Antes de desistir, lembre-se de que o contêiner Redis pode levar alguns segundos para ficar disponível quando você remover toda a pilha.

Mais app.py, você cria um arquivo requirements.txt com dependências do Python (por exemplo, Flask e redis-py), e um Dockerfile que especifica como construir a imagem da sua aplicação web: imagem base do Python (3.7, 3.10 ou qualquer outra), diretório de trabalho, variáveis ​​de ambiente para o Flask, instalação do gcc e dependências do sistema, cópia do requirements.txt, instalação de pacotes e cópia do código.

No Dockerfile, você também marca o porta que exibirá o contêiner (por exemplo, 5000) e você define o comando padrão, normalmente flask run --debug ou algo semelhante, para que inicie automaticamente quando o contêiner for criado.

Com tudo isso pronto, o arquivo compose.yaml define dois serviços: um chamado, por exemplo, web, que é construído a partir do Dockerfile do projeto e expõe a porta 8000 externamente (mapeando a porta 8000 do host para a porta 5000 do contêiner), e outro chamado redis que Baixe a imagem oficial do Redis do Docker Hub..

Para iniciar a aplicação, basta navegar até o diretório do projeto e executar o comando. "docker compose up"O Compose se encarrega de baixar a imagem do Redis, construir a imagem da sua aplicação web e iniciar ambos os serviços na ordem correta.

Depois de estar instalado e funcionando, você acessa com seu navegador o seguinte: http://localhost:8000 (o http://127.0.0.1:8000) e você deverá ver uma mensagem do tipo "Olá Mundo" e um Contador de visitantes que aumenta a cada vez que você recarrega a página. a página. Se você inspecionar as imagens locais com docker image lsVocê verá algo como redis y web criado ou baixado.

Quando você quiser parar com tudo, você pode fazer Pressione CTRL+C no terminal onde você deixou "docker compose up" ou executar docker compose down a partir do diretório do projeto. Isso interromperá e removerá os contêineres criados pelo comando compose.

Melhorando o fluxo de trabalho: Vincule montagens e observe o Compose.

Trabalhar em desenvolvimento com Docker é mais conveniente se Você não precisa reconstruir a imagem. Toda vez que você altera o código. É aí que entram em cena os Bind Mounts e, em versões mais recentes, o Docker Compose Watch.

Uma montagem de diretórios (bind mount) envolve a montagem de uma pasta do seu computador dentro do contêiner. No arquivo compose.yaml, você adiciona uma seção ao serviço web. volumes que mapeia o diretório do projeto para o diretório de trabalho do contêiner, por exemplo .:/codeDessa forma, quaisquer alterações feitas no editor serão refletidas instantaneamente no contêiner.

Se você também ativar o modo de depuração do Flask com a variável FLASK_DEBUG=1, o comando flask run O aplicativo será recarregado automaticamente ao detectar alterações nos arquivos, sem a necessidade de ser interrompido e reiniciado.

O Docker Compose Watch leva isso um passo adiante: você pode usar “docker compose watch” ou “docker compose up –watch” Isso permite que o Compose monitore os arquivos do projeto e sincronize as alterações com os contêineres de forma mais inteligente. Quando você salva um arquivo, ele é copiado para o contêiner e o servidor de desenvolvimento atualiza o aplicativo sem precisar reiniciar todo o contêiner.

Experimente, por exemplo, alterar a mensagem de boas-vindas em app.py de "Olá, mundo!" para uma frase como "Olá do Docker"Salve o arquivo, atualize seu navegador e você verá a nova mensagem instantaneamente, enquanto o contador de visitas continua funcionando sem perder o estado.

E quando você terminar de trabalhar, como sempre, você pode puxar docker compose down para Desligue e limpe os recipientes. que estavam em andamento com aquela pilha.

  Atalhos de teclado no Linux: o guia definitivo para ser mais rápido

Exemplo 2: Aplicativo full stack com frontend, backend e banco de dados

Para visualizar o Docker Compose em uma arquitetura um pouco mais realista, imagine um Aplicativo de lista de tarefas (Lista de tarefas) Com um frontend em Vue.js, uma API em Node.js e um banco de dados MongoDB. Cada parte reside em seu próprio diretório e possui seu próprio Dockerfile.

No repositório, você pode encontrar uma pasta. frontend com o aplicativo Vue e outro backend com o servidor Node. O backend expõe endpoints para Criar, listar, atualizar e excluir tarefase se conecta ao MongoDB para armazená-las. O frontend consome esses endpoints para exibir e gerenciar a lista de tarefas no navegador.

O arquivo docker-compose.yml Localiza-se na raiz do projeto e define três serviços: frontend, backend y databaseO serviço de front-end é construído a partir do Dockerfile na pasta correspondente, geralmente expondo a porta interna 80 e mapeando-a para a porta 5173 do host (por exemplo, para usar a mesma URL do ambiente de desenvolvimento local).

O backend é construído a partir do Dockerfile no diretório backend, expõe a porta 3000 (tanto dentro quanto fora do contêiner, se você quiser simplificar) e declara uma dependência do banco de dados para garantir que o MongoDB esteja disponível na inicialização.

O serviço database use o diretamente Imagem oficial do MongoDB e construir um volume, digamos mongodb_dataem /data/db, que é onde o MongoDB armazena seus dados. Esse volume é declarado na seção superior. volumes a partir do modo de composição, para que os dados persistam mesmo se você excluir e recriar os contêineres.

Finalmente, todos esses serviços se conectam por meio de uma rede personalizada, por exemplo. my-network, definida na seção networksIsso permite que sejam resolvidos pelo nome do serviço (o backend pode se conectar ao Mongo usando o nome do host). database) e que o tráfego está encapsulado nessa rede isolada.

Com a configuração pronta, execute docker compose up No cerne do projeto, está a sua responsabilidade por Crie ou baixe as imagens e execute os três contêineres.Você pode verificar se tudo está em ordem com docker compose ps, e então acessando http://localhost:5173 Para visualizar o aplicativo Vue no seu navegador e criar suas primeiras tarefas.

Redes no Docker Compose: conectando serviços entre si.

As redes são a camada que permite que seus contêineres funcionem. Eles se "enxergam" e conversam de maneira controlada.Por padrão, o Docker já cria redes para o Compose, mas defini-las explicitamente oferece mais clareza e controle sobre o que pode se comunicar com o quê.

Funciona de forma simples: cada serviço inclui um campo. networks onde você indica a quais redes ele pertence e, em seguida, na seção superior. networks Você define essas redes com suas configurações. A abordagem mais comum (e recomendada em muitos casos) é usar o driver. bridge.

Uma rede de pontes cria uma espaço privado rede para seus contêinerescom resolução automática de DNS baseada no nome do serviço. Isso significa que, por exemplo, se o seu serviço de banco de dados se chamar databaseQualquer outro serviço na mesma rede pode se conectar usando apenas database como nome de host.

Em um projeto com frontend, backend e banco de dados, você pode decidir, por exemplo, criar uma rede de frontend e uma rede de backend. O frontend se conectaria ao backend, e o backend ao banco de dados, mas o frontend e o banco de dados... Eles não precisariam necessariamente compartilhar uma rede.reduzir a área de superfície interna exposta.

Em código, isso se traduz em algo tão simples quanto atribuir a rede correspondente a cada serviço e, em seguida, definir essas redes com pontes de driver. No nível do aplicativo, a abordagem mais simples é usar o nome do serviço como host Ao configurar as conexões: de app a databasePor exemplo, simplesmente indicando que o host do banco de dados é "database".

Volumes no Docker Compose: Persistência de dados

Os volumes são a forma recomendada de persistir informações geradas pelos contêineres. Como bases de dadosArquivos de usuário, backups, etc. Eles também são usados ​​para compartilhar dados entre serviços dentro da mesma infraestrutura.

Na seção services Você pode montar volumes diretamente com volumesMas, quando você deseja que esse volume seja acessível por vários contêineres ou deseja gerenciá-lo de forma mais explícita, você também o define na seção superior. volumes do arquivo compose.yaml.

Imagine que você queira configurar um sistema de backup para seu banco de dados. Você teria o serviço de banco de dados montando um volume onde armazena seus dados e outro serviço dedicado a backups que... Monte esse mesmo volume em modo de leitura. Para realizar exportações ou sincronizações sem alterar o contêiner principal.

O Docker permite ajustar a configuração dos volumes com mais parâmetros (tipo de driver, opções específicas para Drivers fatores externos, etc.), mas na maioria dos casos o mais prático é deixar acontecer. O Docker gerencia volumes automaticamente. Sem recorrer a configurações mirabolantes.

O importante é ter clareza sobre quais pastas em seus serviços precisam ser persistentes e declará-las como volumes no Compose para que você não perca dados ao recriar contêineres ou atualizar imagens.

Configurações: gerenciando arquivos de configuração

A seção configs Ele foi projetado para gerenciar arquivos de configuração. de serviços dentro da sua pilha, semelhante a volumes, mas especificamente focado em configuração.

Imagine um servidor Apache ou Nginx rodando em um contêiner Docker. Você provavelmente precisará de... Ajuste seu arquivo de configuração Recriar a imagem sempre que esses arquivos são modificados é ineficiente e irritante, especialmente em ambientes onde os parâmetros são ajustados com frequência.

  Como corrigir o código de erro 24 do Disney Plus

Com configs Você pode especificar no serviço o que deseja. aplicar uma configuração específica e depois descreva-o na seção configsExistem várias maneiras de defini-los, sendo a mais comum:

  • fileA configuração é gerada a partir de um arquivo local.
  • external: se estiver marcado como trueO Compose pressupõe que a configuração já existe e apenas a referencia.
  • name: Nome interno da configuração no Docker, útil ao combinar com external: true.

Dessa forma, você pode atualizar o arquivo de configuração em sua máquina e retornar ao elevar a pilha sem precisar reconstruir a imagem base, mantendo o código da imagem separado da configuração específica do ambiente.

Segredos: credenciais e dados confidenciais

A seção secrets resolve um problema clássicoOnde posso armazenar senhas, chaves de API e outras informações confidenciais sem deixá-las espalhadas pelo código ou pelo arquivo YAML?

Assim como as configurações, os segredos podem ser definidos de diferentes maneiras.O mais comum é:

  • fileO segredo é gerado a partir do conteúdo de um arquivo (por exemplo, um arquivo de texto com uma chave).
  • environmentO segredo é criado usando o valor de uma variável de ambiente do seu sistema.
  • external: indica que o segredo já foi criado e só precisa ser referenciado, útil para evitar sobrescrever segredos que são gerenciados externamente.
  • name: nome interno do segredo, especialmente relevante ao combinar external: true com segredos criados por outra ferramenta.

Com segredos, você pode criar contêineres que precisam acessar essas credenciais. leia-os de forma controlada Sem precisar deixá-los visíveis no repositório de código ou no próprio arquivo compose.yaml, reforçando significativamente a segurança de suas implantações.

Trabalhando com vários arquivos: Compor e incluir

Em projetos de grande porte, não é incomum que sua aplicação seja dividida em diversos serviços, às vezes gerenciados por equipes diferentes. Nesses casos, é prático... Separe a configuração em vários arquivos Compose. para melhor modularizar a arquitetura.

Uma abordagem típica é ter um compose.yaml arquivo principal para o aplicativo e outros arquivos para partes da infraestrutura. Por exemplo, você pode Mova a definição do Redis. ou outros serviços de suporte a arquivos infra.yaml e, no geral, escreva apenas o que diz respeito diretamente ao seu aplicativo.

Para fazer isso, você cria o arquivo. infra.yaml com sua própria seção services onde você deixa, por exemplo, o serviço Redis completo. Então, no seu compose.yaml principal, você adiciona uma seção include que aponta para o arquivo infra.yaml.

Quando você corre docker compose up A partir do diretório do projeto, Compose. Combine os dois arquivos E isso exibe todos os serviços como se estivessem em um único arquivo YAML, mas você ainda mantém a lógica separada e mais organizada.

Essa técnica facilita a manutenção dos arquivos Compose por diferentes equipes e a montagem da aplicação global usando includes, o que é muito útil em arquiteturas com dezenas de contêineres ou ambientes com muita infraestrutura compartilhada.

Comandos essenciais do Docker Compose

Embora o Compose tenha um bom catálogo de comandos, no dia a dia a maioria das pessoas usa alguns deles de forma recorrenteÉ importante dominá-las porque são elas que definem seu fluxo de trabalho.

O mais importante é docker compose upEste comando cria as imagens necessárias (caso ainda não existam), cria os contêineres, configura redes e volumes e inicia todos os serviços definidos no seu arquivo Compose. É o comando que você usa quando deseja iniciar seu conjunto de serviços.

Geralmente é combinado com a opção -d para executá-lo no modo "desanexado"Ou seja, em segundo plano. Dessa forma, você não sobrecarrega o terminal com registros e pode continuar usando essa sessão para outros comandos. Por exemplo: docker compose up -d.

Para parar e limpar o que você levantou, você usa docker compose downque interrompe e remove contêineres, redes e, opcionalmente, imagens e volumes associados. Duas flags muito comuns aqui são --rmi (para excluir imagens) e -v (para remover volumes definidos na seção volumes).

Se você quiser ver quais contêineres fazem parte do projeto e qual o status deles, você pode executar o seguinte comando: docker compose psEsta lista apresenta cada serviço, seu status (ativo, encerrado, etc.) e as portas expostas, o que é muito útil para verificar se tudo está funcionando corretamente após uma reinicialização. up.

Ao iniciar seu stack em modo detached, os logs não aparecem no terminal. Para visualizá-los, você precisa usar... docker compose logsglobalmente ou filtrando por serviço. A bandeira -f Permite rastrear registros em tempo real, o que é muito útil para depurar um serviço específico sem necessidade de acessar o interior do recipiente.

Fluxo de trabalho típico: definir compose.yaml, execute um docker compose up -d, verifique com docker compose ps, revise os registros com docker compose logs -f <servicio> Se algo der errado, e quando você terminar, use docker compose down Deixar tudo limpo.

Se você alguma vez se perder, docker compose --help Ele mostra a lista de subcomandos e opções disponíveis para ajudar você a lembrar o que cada item faz sem precisar consultar a documentação.

Tendo em vista tudo o que foi exposto acima, ferramenta chave Para quem trabalha com contêineres além de projetos individuais, o Compose é uma ferramenta excelente. Ele permite desenvolver diretamente em um ambiente muito semelhante (ou idêntico) ao de produção, controlar serviços, redes e dados a partir de um simples arquivo YAML e evitar uma série de problemas de compatibilidade e implantação que inevitavelmente surgem ao trabalhar apenas "localmente", sem contêineres. Depois que você se acostuma a escrever um bom arquivo YAML do Compose para seus projetos, é difícil voltar atrás.