Guia Completo para Docker Compose: Criação e Orquestração de Aplicações Multi-Containers
Introdução Geral
O Docker Compose é uma ferramenta essencial para o desenvolvimento e a operação de aplicações multi-containers. Projetado para simplificar a orquestração e o gerenciamento de containers, o Docker Compose permite que você defina, configure e execute todos os serviços necessários para sua aplicação em um único arquivo docker-compose.yml
. Esse recurso é especialmente valioso em ambientes de desenvolvimento e produção, onde diferentes componentes de uma aplicação — como servidores web, bancos de dados e sistemas de cache — precisam trabalhar em conjunto.
Este tutorial aborda o Docker Compose de forma completa e detalhada, desde a instalação e configuração inicial até práticas avançadas para escalonamento, persistência de dados e deploy em produção. Ao final, você terá o conhecimento necessário para configurar ambientes multi-containers robustos e seguros, seja para desenvolvimento, testes ou produção.
Sumário
- Introdução ao Docker Compose
- Instalação e Configuração do Docker Compose
- Estrutura do Arquivo
docker-compose.yml
- Configurando Serviços e Containers
- Configurando Volumes para Persistência de Dados
- Configurando Redes e Comunicação entre Serviços
- Comandos Essenciais do Docker Compose
- Variáveis de Ambiente e
.env
no Docker Compose - Build de Imagens Customizadas com Docker Compose
- Escalando Serviços com Docker Compose
- Saúde e Monitoramento de Containers com Healthchecks
- Usando Dependências de Inicialização e Ordem de Inicialização
- Práticas de Deploy em Produção com Docker Compose
- Executando Comandos em Containers com Docker Compose
- Troubleshooting e Solução de Problemas Comuns
1. Introdução ao Docker Compose
Objetivo
Apresentar o que é o Docker Compose, suas principais vantagens para orquestração de containers, e como ele se diferencia do Docker CLI.
Conteúdo
- O que é o Docker Compose?
- Benefícios do Docker Compose para aplicações multi-containers
- Cenários ideais para uso do Docker Compose
O que é o Docker Compose?
O Docker Compose é uma ferramenta que permite definir e gerenciar ambientes com múltiplos containers Docker de forma declarativa. Com o Compose, você define os serviços, volumes, redes e outras configurações necessárias em um arquivo docker-compose.yml
, permitindo que todos os containers de uma aplicação sejam iniciados com um único comando.
Em vez de criar e configurar containers individualmente, o Compose simplifica o processo, sendo uma excelente ferramenta para gerenciar aplicações multi-containers, como uma aplicação web com um banco de dados e um serviço de cache.
Diferença entre Docker CLI e Docker Compose
Docker CLI | Docker Compose |
---|---|
Gerencia containers individualmente | Orquestra múltiplos containers simultaneamente |
Usado para comandos específicos (docker run , docker build ) |
Usa um arquivo docker-compose.yml para definir toda a infraestrutura de containers |
Focado em operações de um container por vez | Ideal para arquiteturas com vários serviços integrados |
Benefícios do Docker Compose para Aplicações Multi-Containers
- Configuração Centralizada: O Compose permite definir todos os aspectos da infraestrutura (serviços, volumes, redes) em um único arquivo
docker-compose.yml
, simplificando o gerenciamento e a versão do ambiente. - Orquestração de Múltiplos Serviços: Ideal para arquiteturas baseadas em microsserviços, o Docker Compose facilita o desenvolvimento, teste e orquestração de vários serviços interdependentes.
- Automação e Consistência: O Compose assegura que o ambiente configurado seja o mesmo em diferentes estágios de desenvolvimento (ex. desenvolvimento, teste e produção), promovendo consistência e simplificando o processo de automação.
- Escalabilidade: Docker Compose permite escalar serviços horizontalmente com facilidade, tornando-o uma boa escolha para projetos que exigem aumento da capacidade de processamento com apenas alguns comandos.
Exemplos de Cenários Onde o Docker Compose é Ideal
-
Desenvolvimento de Aplicações Web com Backend Completo: Com o Docker Compose, uma aplicação web pode ser desenvolvida junto a seus serviços necessários, como um banco de dados (MySQL, PostgreSQL), um serviço de cache (Redis) e uma API REST.
-
Testes Automatizados de Sistemas Complexos: O Compose permite configurar ambientes complexos com bancos de dados e serviços externos, mantendo consistência em testes automatizados.
-
Ambientes de Desenvolvimento Local Replicáveis: O Compose é amplamente usado para criar ambientes de desenvolvimento local que são uma réplica precisa dos ambientes de produção, o que ajuda a evitar problemas de configuração ao mover o código para produção.
-
Orquestração de Aplicações Baseadas em Microsserviços: Para arquiteturas baseadas em microsserviços, o Compose facilita o gerenciamento de serviços interdependentes, garantindo que todos os containers estejam disponíveis e funcionando em conjunto.
2. Instalação e Configuração do Docker Compose
Objetivo
Ensinar como instalar e configurar o Docker Compose em diferentes sistemas operacionais, além de garantir que a versão esteja atualizada e pronta para uso em desenvolvimento e produção.
Conteúdo
- Instalação do Docker Compose no Linux, Windows e Mac
- Verificação da Instalação
- Requisitos e Atualizações
Instalação do Docker Compose
O Docker Compose é uma ferramenta separada do Docker, mas frequentemente incluída no pacote de instalação principal do Docker Desktop para Windows e Mac. Para o Linux, pode ser necessário instalá-lo manualmente.
1. Instalação no Linux
No Linux, o Docker Compose pode ser instalado diretamente via linha de comando. Confira as instruções a seguir:
1
2
3
4
5
6
7
8
# Baixar a versão mais recente do Docker Compose (confirme a versão em https://github.com/docker/compose/releases)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Dar permissão de execução ao binário do Docker Compose
sudo chmod +x /usr/local/bin/docker-compose
# Verificar se a instalação foi bem-sucedida
docker-compose --version
Nota: Certifique-se de substituir
v2.10.2
pela versão mais recente disponível.
2. Instalação no Windows e Mac
Para Windows e Mac, o Docker Compose é normalmente incluído no Docker Desktop. Siga os passos abaixo para garantir que o Docker Compose está disponível:
- Baixar Docker Desktop: Acesse o site oficial do Docker Desktop e faça o download para o seu sistema operacional.
- Instalação: Siga o assistente de instalação. Durante o processo, o Docker Desktop instalará automaticamente o Docker Compose.
-
Verificação da Instalação: Após a instalação, abra um terminal e execute o comando:
1
docker-compose --version
Se o comando exibir a versão, o Docker Compose está pronto para uso.
Verificação da Instalação
Após instalar o Docker Compose, execute o seguinte comando para garantir que a instalação foi bem-sucedida:
1
docker-compose --version
A saída deve ser semelhante a:
1
Docker Compose version v2.10.2
Se a versão for exibida, significa que o Docker Compose está instalado corretamente e pronto para configurar e gerenciar aplicações multi-containers.
Requisitos e Atualizações
Requisitos de Sistema
- Docker: O Docker Compose depende do Docker, então é necessário ter o Docker instalado e funcionando antes de usar o Compose.
- Permissões de Administrador: Para instalar e configurar o Docker Compose no Linux, você precisará de permissões de superusuário.
Atualização do Docker Compose
Para garantir que você tenha a versão mais recente com os últimos recursos e correções de segurança, é importante atualizar o Docker Compose regularmente.
Passos para Atualização no Linux:
- Remova a versão antiga (opcional):
1
sudo rm /usr/local/bin/docker-compose
- Reinstale a versão mais recente, repetindo o processo de instalação acima.
Atualização no Docker Desktop (Windows e Mac): No Windows e Mac, o Docker Compose é atualizado automaticamente junto com o Docker Desktop. Para verificar se há atualizações, acesse o Docker Desktop, vá até as configurações e verifique a seção de atualizações.
Resumo
Sistema Operacional | Comando de Instalação | Verificação de Versão |
---|---|---|
Linux | sudo curl -L "https://github.com/docker/compose/releases/download/v<versao>/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose |
docker-compose --version |
Windows | Incluído com Docker Desktop. Baixe e instale o Docker Desktop a partir do site oficial. | docker-compose --version |
Mac | Incluído com Docker Desktop. Baixe e instale o Docker Desktop a partir do site oficial. | docker-compose --version |
Conclusão
Com o Docker Compose instalado e configurado, você está pronto para começar a definir e orquestrar ambientes multi-containers. No próximo capítulo, Estrutura do Arquivo docker-compose.yml
, vamos explorar a estrutura e as principais diretivas do arquivo docker-compose.yml
, que é a base para configurar serviços no Docker Compose.
3. Estrutura do Arquivo docker-compose.yml
Objetivo
Apresentar a estrutura e as principais diretivas do arquivo docker-compose.yml
, que é o centro da configuração de aplicações multi-containers com Docker Compose.
Conteúdo
- Introdução às Diretivas do Arquivo
docker-compose.yml
version
services
volumes
networks
- Estruturação e Organização do Arquivo YAML
- Exemplo Simples de Configuração com Dois Serviços
Introdução às Diretivas do Arquivo docker-compose.yml
O arquivo docker-compose.yml
define todos os serviços, redes, volumes e outras configurações necessárias para rodar a aplicação. Abaixo estão as principais diretivas que compõem esse arquivo.
1. version
A diretiva version
especifica a versão do formato de arquivo Compose. É importante escolher uma versão compatível com os recursos que você pretende usar e com a versão do Docker Compose instalada.
Exemplo:
1
version: '3.8'
As versões mais comuns são 3
, 3.8
e 2
. A versão 3.8
é recomendada, pois oferece suporte aos recursos mais recentes e é ideal para a maioria das aplicações modernas.
2. services
A seção services
é onde você define cada container que a aplicação precisa. Para cada serviço, você especifica a imagem, portas, variáveis de ambiente, comandos e outras configurações.
Exemplo:
1
2
3
4
5
6
7
8
9
10
services:
web:
image: nginx:alpine
ports:
- "80:80"
db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
No exemplo acima:
- O serviço
web
usa a imagemnginx:alpine
e expõe a porta 80. - O serviço
db
usa a imagempostgres:13
e define variáveis de ambiente para configurar o banco de dados.
3. volumes
A diretiva volumes
é usada para definir volumes persistentes que serão montados nos containers, permitindo o armazenamento de dados entre reinicializações.
Exemplo:
1
2
volumes:
db_data:
Ao definir um volume no nível principal do arquivo, você o torna acessível para qualquer serviço que precise de armazenamento persistente.
4. networks
A diretiva networks
permite criar redes personalizadas para os serviços. Isso possibilita controlar a comunicação entre os containers e definir redes isoladas para segurança.
Exemplo:
1
2
3
networks:
backend:
driver: bridge
A criação de redes permite que você configure a comunicação entre containers de maneira mais segura e organizada, definindo regras de isolamento e acessibilidade.
Estruturação e Organização do Arquivo YAML
A estrutura YAML do docker-compose.yml
é simples, mas é essencial manter a indentação correta para evitar erros. Seguir um padrão organizacional ajuda na leitura e manutenção do arquivo. Alguns pontos para estruturar melhor o arquivo incluem:
- Definir
version
na primeira linha - Listar serviços principais e suas configurações logo após
services
- Separar
volumes
enetworks
na parte inferior
Exemplo Completo Estruturado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
networks:
backend:
driver: bridge
Exemplo Simples de Configuração com Dois Serviços
Aqui está um exemplo de um arquivo docker-compose.yml
simples que define dois serviços, um servidor web e um banco de dados, e inclui configurações de volume e rede:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: '3.8'
services:
app:
image: myapp:latest
ports:
- "8080:8080"
networks:
- backend
database:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- db_storage:/var/lib/mysql
networks:
- backend
volumes:
db_storage:
networks:
backend:
driver: bridge
Neste exemplo:
- O serviço
app
expõe a porta 8080 e se conecta à redebackend
. - O serviço
database
usa a imagemmysql:5.7
, define uma senha de root e monta o volumedb_storage
para persistência. - A rede
backend
conecta ambos os serviços, permitindo que eles se comuniquem diretamente.
Conclusão
Neste capítulo, exploramos a estrutura básica do arquivo docker-compose.yml
e as principais diretivas usadas para definir os serviços, volumes e redes. No próximo capítulo, Configurando Serviços e Containers, veremos como configurar cada serviço individualmente dentro do docker-compose.yml
, incluindo a definição de variáveis de ambiente, portas, comandos e mais.
4. Configurando Serviços e Containers
Objetivo
Demonstrar como configurar cada serviço individualmente dentro do docker-compose.yml
, usando opções como image
, build
, ports
, environment
, entre outras, para personalizar containers.
Conteúdo
- Definindo Containers em
services
- Configuração de Opções do Serviço
image
build
ports
environment
- Exemplo Prático de Configuração com um Serviço Web e Banco de Dados
Definindo Containers em services
No Docker Compose, cada container é definido como um serviço na seção services
do arquivo docker-compose.yml
. Para cada serviço, podemos especificar uma série de configurações que determinam o comportamento e as características do container.
Configuração de Opções do Serviço
Abaixo estão algumas das principais opções de configuração de serviço que podem ser utilizadas:
1. image
A opção image
define qual imagem Docker será usada para o serviço. Pode ser uma imagem oficial do Docker Hub ou uma imagem personalizada de um repositório privado.
Exemplo:
1
2
3
services:
web:
image: nginx:alpine
2. build
A opção build
permite compilar uma imagem personalizada para o serviço diretamente com o Docker Compose, usando um diretório que contém um Dockerfile
. Isso é útil quando você deseja construir imagens a partir de código-fonte e configurá-las com o Compose.
Exemplo:
1
2
3
4
5
services:
app:
build:
context: ./app
dockerfile: Dockerfile
No exemplo, o Docker Compose usará o Dockerfile
localizado no diretório ./app
para construir a imagem.
3. ports
A opção ports
define quais portas serão expostas pelo container e como elas serão mapeadas para o host. O formato host:container
é usado para mapear as portas.
Exemplo:
1
2
3
4
5
services:
web:
image: nginx:alpine
ports:
- "8080:80"
Neste exemplo, a porta 80 do container está mapeada para a porta 8080 do host.
4. environment
A opção environment
permite definir variáveis de ambiente específicas para cada serviço. Isso é útil para configurar informações como credenciais, configurações de banco de dados e outros valores que podem variar entre diferentes ambientes.
Exemplo:
1
2
3
4
5
6
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example_password
MYSQL_DATABASE: example_db
Neste exemplo, as variáveis MYSQL_ROOT_PASSWORD
e MYSQL_DATABASE
configuram o serviço de banco de dados com a senha de root e o nome do banco.
Exemplo Prático de Configuração com um Serviço Web e Banco de Dados
Aqui está um exemplo de configuração docker-compose.yml
que cria dois serviços: uma aplicação web e um banco de dados MySQL. Esse exemplo cobre as principais opções de configuração mencionadas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile
ports:
- "8080:80"
environment:
- APP_ENV=production
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example_password
MYSQL_DATABASE: example_db
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Neste exemplo:
- O serviço
web
é construído a partir de um Dockerfile localizado no diretório./web
e expõe a porta 8080 no host para a porta 80 no container. - O serviço
db
usa a imagemmysql:5.7
e é configurado com variáveis de ambiente para definir a senha e o banco de dados inicial. - Um volume
db_data
é montado em/var/lib/mysql
no containerdb
, garantindo a persistência dos dados do banco de dados.
Conclusão
Configurando serviços no Docker Compose, você pode personalizar o comportamento de cada container de forma flexível. Definindo imagens, portas, variáveis de ambiente e dependências, é possível criar aplicações multi-containers que compartilham configurações e se comunicam de maneira integrada. No próximo capítulo, Configurando Volumes para Persistência de Dados, exploraremos como usar volumes no Compose para armazenar dados entre reinicializações e garantir a persistência necessária para aplicativos de produção.
5. Configurando Volumes para Persistência de Dados
Objetivo
Ensinar como configurar volumes no Docker Compose para persistir dados entre reinicializações de containers, garantindo que informações essenciais, como dados de banco de dados e arquivos de configuração, permaneçam preservadas.
Conteúdo
- Introdução ao Uso de Volumes no Docker Compose
- Definindo Volumes no
docker-compose.yml
- Montagem de Volumes em Serviços
- Exemplos Práticos de Volumes com Banco de Dados e Armazenamento de Arquivos
Introdução ao Uso de Volumes no Docker Compose
Volumes em Docker são uma forma de armazenamento persistente que permite que dados sejam mantidos mesmo após o container ser destruído ou reiniciado. Em aplicações de produção, volumes são essenciais para armazenar dados críticos que não podem ser perdidos, como informações de bancos de dados, arquivos de configuração e logs.
Definindo Volumes no docker-compose.yml
No Docker Compose, os volumes podem ser definidos na seção volumes
, no nível mais alto do arquivo docker-compose.yml
. Definir um volume globalmente torna-o acessível a qualquer serviço que precise de armazenamento persistente.
Exemplo:
1
2
3
volumes:
db_data:
app_logs:
Neste exemplo, dois volumes são definidos:
db_data
: Pode ser usado para armazenar dados de um banco de dados.app_logs
: Pode ser utilizado para armazenar logs da aplicação.
Montagem de Volumes em Serviços
Após definir um volume, é necessário montá-lo em um serviço específico. Isso é feito na configuração do serviço, utilizando a diretiva volumes
. Cada volume pode ser montado em um diretório específico dentro do container, de acordo com as necessidades do serviço.
Sintaxe:
1
2
volumes:
- volume_nome:/caminho/dentro/do/container
Exemplos Práticos de Volumes com Banco de Dados e Armazenamento de Arquivos
Abaixo, apresentamos exemplos práticos de como montar volumes para persistir dados de um banco de dados MySQL e arquivos de uma aplicação web.
Exemplo 1: Volume para Persistência de Banco de Dados
Neste exemplo, vamos configurar um volume db_data
para armazenar os dados de um serviço de banco de dados MySQL.
1
2
3
4
5
6
7
8
9
10
11
12
13
version: '3.8'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: my_database
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Explicação:
- Volume
db_data
: Montado no diretório/var/lib/mysql
dentro do container. Este é o diretório padrão onde o MySQL armazena seus dados, garantindo que o banco de dados persista entre reinicializações do container.
Exemplo 2: Volume para Armazenamento de Arquivos da Aplicação
Neste exemplo, configuramos um volume app_files
para armazenar dados da aplicação, como uploads de usuários.
1
2
3
4
5
6
7
8
9
10
11
12
version: '3.8'
services:
web:
image: nginx:alpine
volumes:
- app_files:/usr/share/nginx/html/uploads
ports:
- "8080:80"
volumes:
app_files:
Explicação:
- Volume
app_files
: Montado no diretório/usr/share/nginx/html/uploads
dentro do container Nginx. Esse diretório é onde os arquivos de uploads da aplicação são armazenados, garantindo que eles sejam preservados mesmo se o containerweb
for destruído ou atualizado.
Conclusão
O uso de volumes no Docker Compose é essencial para a persistência de dados em containers Docker. Com volumes, dados críticos, como informações de bancos de dados e arquivos de aplicação, permanecem disponíveis entre reinicializações, atualizações e recriações de containers. No próximo capítulo, Configurando Redes e Comunicação entre Serviços, exploraremos como configurar redes no Docker Compose para permitir que containers se comuniquem com segurança e eficiência.
6. Configurando Redes e Comunicação entre Serviços
Objetivo
Demonstrar como configurar redes no Docker Compose para conectar serviços de forma segura e permitir comunicação entre containers.
Conteúdo
- Introdução ao Uso de Redes no Docker Compose
- Tipos de Redes e Suas Aplicações (
bridge
,host
,overlay
) - Configurando Redes no
docker-compose.yml
- Exemplo Prático de Rede Personalizada para Comunicação Segura
Introdução ao Uso de Redes no Docker Compose
No Docker Compose, redes são essenciais para controlar como os containers se conectam entre si e com o mundo externo. Usando redes, é possível configurar a comunicação entre serviços e limitar o acesso externo a containers específicos, criando um ambiente mais seguro e controlado.
Tipos de Redes e Suas Aplicações
O Docker Compose suporta diferentes tipos de redes que servem a propósitos variados. Aqui estão os principais:
bridge
: Rede padrão do Docker, usada para conectar containers em um único host. Ideal para isolar serviços e configurar comunicações entre containers em um mesmo host.host
: Rede que usa a pilha de rede do host, onde o container compartilha o endereço IP do host. Comumente usada para containers que precisam de desempenho máximo de rede.overlay
: Rede que permite comunicação entre containers em múltiplos hosts, ideal para uso em clusters Docker Swarm.
Para configurações locais e de desenvolvimento, a rede bridge
é geralmente a mais indicada, enquanto em clusters Docker Swarm a rede overlay
permite orquestração entre múltiplos nós.
Configurando Redes no docker-compose.yml
Você pode configurar redes no nível mais alto do arquivo docker-compose.yml
para definir redes que estarão disponíveis para os serviços ou diretamente dentro de cada serviço para especificar a rede que ele deve utilizar.
Definindo Redes no Nível Principal
No exemplo abaixo, duas redes são definidas: frontend
e backend
.
1
2
3
4
5
networks:
frontend:
driver: bridge
backend:
driver: bridge
Conectando Serviços a Redes
Uma vez que as redes foram definidas, você pode conectá-las aos serviços no docker-compose.yml
, especificando em quais redes cada serviço deve estar presente.
Exemplo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
networks:
- frontend
app:
image: myapp:latest
networks:
- frontend
- backend
db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
Explicação:
- O serviço
web
está conectado apenas à redefrontend
, o que significa que ele só pode se comunicar com containers que estão na mesma redefrontend
. - O serviço
app
está conectado às redesfrontend
ebackend
, permitindo comunicação tanto com o serviçoweb
quanto com o serviçodb
. - O serviço
db
está conectado somente à redebackend
, mantendo-o isolado da redefrontend
e, portanto, inacessível diretamente pelo serviçoweb
.
Essa configuração de rede aumenta a segurança e ajuda a controlar o fluxo de dados entre serviços.
Exemplo Prático de Rede Personalizada para Comunicação Segura
Abaixo está um exemplo de configuração de rede personalizada que define a comunicação entre uma aplicação web, um backend e um banco de dados. Nesse exemplo, o banco de dados é isolado do serviço web, acessível apenas pelo backend.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
networks:
- frontend
backend:
image: myapp:backend
networks:
- frontend
- backend
database:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: secure_password
volumes:
- db_data:/var/lib/mysql
networks:
- backend
volumes:
db_data:
networks:
frontend:
driver: bridge
backend:
driver: bridge
Explicação do Exemplo:
- Isolamento do Banco de Dados: A rede
backend
conecta odatabase
aobackend
, mas não aoweb
, garantindo que o banco de dados só seja acessível pelo serviço que realmente precisa dele. - Comunicação Controlada: O
backend
se comunica tanto com odatabase
quanto com oweb
, permitindo o fluxo de dados necessário, enquanto o serviçoweb
permanece isolado da camada de dados. - Persistência: O volume
db_data
mantém os dados do banco mesmo após a reinicialização dos containers.
Esse exemplo é uma configuração segura e comum para sistemas de produção, onde diferentes serviços têm níveis variados de acesso e comunicação.
Conclusão
Configurar redes no Docker Compose é fundamental para controlar a comunicação entre serviços de maneira eficiente e segura. Com redes personalizadas, você pode definir quais serviços devem se comunicar e isolar aqueles que não precisam estar acessíveis a outros containers, melhorando a segurança do ambiente. No próximo capítulo, Comandos Essenciais do Docker Compose, vamos explorar os comandos principais para gerenciar aplicações multi-containers com Docker Compose.
7. Comandos Essenciais do Docker Compose
Objetivo
Apresentar os principais comandos do Docker Compose que facilitam a gestão de aplicações multi-containers, incluindo comandos para iniciar, parar, escalar, visualizar logs e inspecionar o status dos serviços.
Conteúdo
- Principais Comandos do Docker Compose
docker-compose up
docker-compose down
docker-compose ps
- Controle de Logs com
docker-compose logs
- Outros Comandos Úteis
docker-compose restart
docker-compose exec
- Exemplo de Uso dos Comandos em Diferentes Cenários
Principais Comandos do Docker Compose
Aqui estão alguns dos comandos mais utilizados para iniciar, parar e monitorar aplicações no Docker Compose.
1. docker-compose up
O comando docker-compose up
cria e inicia os containers definidos no arquivo docker-compose.yml
.
- Execução do Comando:
1
docker-compose up
- Execução em Segundo Plano (Modo Detach): Use a opção
-d
para rodar os containers em segundo plano, permitindo que o terminal fique livre para outros comandos.1
docker-compose up -d
Este comando compila as imagens, configura redes e inicia os containers, facilitando a inicialização rápida do ambiente.
2. docker-compose down
O comando docker-compose down
encerra e remove todos os containers, redes e volumes criados pelo comando up
, mas mantém as imagens.
- Execução do Comando:
1
docker-compose down
- Remoção de Volumes Associados: Adicione a opção
-v
para remover também os volumes persistentes.1
docker-compose down -v
Esse comando é útil para “limpar” o ambiente após o uso, garantindo que não haja containers e redes remanescentes.
3. docker-compose ps
O comando docker-compose ps
exibe uma lista de todos os containers que estão sendo gerenciados pelo Compose, mostrando informações como status e portas expostas.
- Execução do Comando:
1
docker-compose ps
Esse comando é útil para verificar o status dos containers e confirmar que todos os serviços estão ativos.
Controle de Logs com docker-compose logs
O comando docker-compose logs
exibe os logs gerados pelos containers em tempo real. Ele é útil para depurar problemas e monitorar o funcionamento dos serviços.
- Exibir Logs de Todos os Serviços:
1
docker-compose logs
- Exibir Logs de um Serviço Específico: Especifique o nome do serviço para filtrar os logs.
1
docker-compose logs web
- Exibir Logs em Tempo Real: Adicione a opção
-f
para seguir os logs em tempo real, permitindo monitorar a execução contínua.1
docker-compose logs -f
Outros Comandos Úteis
1. docker-compose restart
O comando docker-compose restart
reinicia todos os containers ou containers específicos, sem precisar parar o ambiente por completo.
- Reiniciar Todos os Serviços:
1
docker-compose restart
- Reiniciar um Serviço Específico:
1
docker-compose restart web
Esse comando é especialmente útil após alterações de configuração que não exigem a recriação completa dos containers.
2. docker-compose exec
O comando docker-compose exec
permite executar comandos específicos dentro de um container em execução. É uma alternativa prática para entrar no container e executar comandos sem interromper o serviço.
- Execução de Comandos em um Container Específico:
1
docker-compose exec web sh
Nesse exemplo, estamos executando um shell interativo (sh
) dentro do container do serviço web
. Esse comando é útil para realizar verificações, rodar comandos de administração e depurar o container.
Exemplo de Uso dos Comandos em Diferentes Cenários
Vamos explorar alguns cenários práticos em que esses comandos podem ser utilizados para gerenciar o ciclo de vida de uma aplicação multi-containers.
-
Iniciar o Ambiente e Visualizar Logs em Tempo Real
1 2
docker-compose up -d docker-compose logs -f
Primeiro, iniciamos o ambiente em segundo plano com
up -d
e, em seguida, visualizamos os logs em tempo real para acompanhar o status dos containers. -
Reiniciar um Serviço após Alteração de Configuração
1
docker-compose restart web
Este comando reinicia apenas o serviço
web
, útil após modificar configurações no arquivodocker-compose.yml
para esse serviço. -
Executar Comandos Dentro do Container
1
docker-compose exec db mysql -u root -p
Neste exemplo, acessamos o banco de dados MySQL diretamente dentro do container
db
, permitindo realizar tarefas administrativas diretamente. -
Encerrar e Limpar o Ambiente
1
docker-compose down -v
Esse comando encerra todos os containers e remove também os volumes, garantindo uma limpeza completa do ambiente para futuras execuções.
Conclusão
Com os comandos essenciais do Docker Compose, você tem controle total sobre o ciclo de vida dos containers, facilitando o gerenciamento de aplicações multi-containers de forma simples e eficiente. No próximo capítulo, Variáveis de Ambiente e .env
no Docker Compose, veremos como gerenciar configurações dinâmicas e sensíveis usando um arquivo .env
, permitindo maior flexibilidade e segurança.
8. Variáveis de Ambiente e .env
no Docker Compose
Objetivo
Mostrar como gerenciar variáveis de ambiente e configurações dinâmicas no Docker Compose usando um arquivo .env
. Isso facilita o controle de configurações sensíveis e permite que valores dinâmicos sejam configurados de forma segura e consistente entre diferentes ambientes.
Conteúdo
- Introdução ao Uso de Variáveis de Ambiente no Docker Compose
- Criação e Configuração de um Arquivo
.env
- Referência a Variáveis de Ambiente no
docker-compose.yml
- Exemplo Prático de Configuração de Variáveis Sensíveis
Introdução ao Uso de Variáveis de Ambiente no Docker Compose
No Docker Compose, variáveis de ambiente permitem parametrizar a configuração de serviços e ajustar valores dinâmicos sem a necessidade de modificar diretamente o arquivo docker-compose.yml
. As variáveis são usadas para definir dados sensíveis, como credenciais, URLs de APIs e portas, promovendo uma configuração mais flexível e segura.
O Compose busca variáveis de ambiente de duas fontes principais:
- Variáveis Definidas no Arquivo
.env
: Ideal para armazenar variáveis específicas para o ambiente. - Variáveis do Ambiente do Sistema: Valores definidos diretamente no terminal ou no sistema operacional.
Criação e Configuração de um Arquivo .env
O arquivo .env
é um arquivo de texto simples onde cada linha contém uma variável de ambiente na forma NOME_VARIAVEL=valor
. Ele deve estar no mesmo diretório que o arquivo docker-compose.yml
para que o Compose o reconheça automaticamente.
Exemplo de um Arquivo .env
:
1
2
3
4
5
6
# Arquivo .env
MYSQL_ROOT_PASSWORD=strong_password
MYSQL_DATABASE=my_database
MYSQL_USER=my_user
MYSQL_PASSWORD=my_user_password
APP_PORT=8080
No exemplo acima:
- Variáveis de configuração para um serviço MySQL são definidas (
MYSQL_ROOT_PASSWORD
,MYSQL_DATABASE
,MYSQL_USER
,MYSQL_PASSWORD
). - Uma variável
APP_PORT
especifica a porta onde a aplicação deve estar disponível.
Referência a Variáveis de Ambiente no docker-compose.yml
Dentro do arquivo docker-compose.yml
, as variáveis de ambiente podem ser referenciadas com a sintaxe ${NOME_VARIAVEL}
. Se a variável for encontrada no arquivo .env
ou nas variáveis do ambiente do sistema, seu valor será substituído automaticamente.
Exemplo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "${APP_PORT}:80"
environment:
- NGINX_HOST=${HOST}
- NGINX_PORT=${APP_PORT}
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Explicação:
- A variável
APP_PORT
no serviçoweb
define a porta de exposição do Nginx. - No serviço
db
, as variáveis de ambiente para o MySQL (MYSQL_ROOT_PASSWORD
,MYSQL_DATABASE
,MYSQL_USER
,MYSQL_PASSWORD
) são atribuídas diretamente a partir do arquivo.env
.
Se o arquivo .env
contiver as variáveis necessárias, o Compose as lerá automaticamente quando o comando docker-compose up
for executado.
Exemplo Prático de Configuração de Variáveis Sensíveis
Vamos configurar um ambiente de exemplo usando variáveis de ambiente para gerenciar credenciais e portas, e usaremos o arquivo .env
para centralizar essas configurações.
-
Crie o Arquivo
.env
:Crie o arquivo
.env
no mesmo diretório que odocker-compose.yml
com o seguinte conteúdo:1 2 3 4 5
MYSQL_ROOT_PASSWORD=my_secret_password MYSQL_DATABASE=production_db MYSQL_USER=prod_user MYSQL_PASSWORD=prod_password APP_PORT=3000
-
Configure o Arquivo
docker-compose.yml
:No arquivo
docker-compose.yml
, faça referência às variáveis de ambiente definidas no.env
:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
version: '3.8' services: web: image: myapp:latest ports: - "${APP_PORT}:80" environment: - APP_ENV=production - APP_DEBUG=false db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - db_data:/var/lib/mysql volumes: db_data:
-
Execute o Docker Compose:
Ao executar o comando
docker-compose up
, o Docker Compose lerá as variáveis do arquivo.env
e as aplicará aos serviços conforme configurado nodocker-compose.yml
.1
docker-compose up -d
Isso criará o ambiente com as configurações dinâmicas de porta e banco de dados, sem a necessidade de alterar o arquivo
docker-compose.yml
diretamente.
Conclusão
O uso de variáveis de ambiente com .env
no Docker Compose permite configurar aplicações de forma flexível e segura, facilitando a mudança de valores entre ambientes sem modificar o arquivo principal docker-compose.yml
. No próximo capítulo, Build de Imagens Customizadas com Docker Compose, vamos explorar como construir imagens personalizadas diretamente a partir do Docker Compose, usando um Dockerfile
e variáveis de build para personalização adicional.
9. Build de Imagens Customizadas com Docker Compose
Objetivo
Ensinar como construir imagens personalizadas diretamente pelo Docker Compose, configurando o contexto de build, definindo argumentos, e aplicando configurações de cache para otimizar o processo de build.
Conteúdo
- Introdução ao Build de Imagens com Docker Compose
- Definindo
build
nodocker-compose.yml
- Configuração de
context
,dockerfile
eargs
- Exemplo de Configuração para Construção de Imagens Personalizadas
Introdução ao Build de Imagens com Docker Compose
Em projetos onde o código-fonte precisa ser transformado em uma imagem Docker antes de ser executado, o Docker Compose pode gerenciar a construção dessas imagens. Isso é feito usando a opção build
, que permite definir um diretório de contexto contendo o código e um Dockerfile
com as instruções para criar a imagem.
Definindo build
no docker-compose.yml
A diretiva build
é usada no Docker Compose para compilar uma imagem a partir de um Dockerfile
específico. Dentro de build
, é possível especificar o diretório de contexto (context
), o caminho do Dockerfile
e argumentos de build (args
) que podem ser usados para customizar a imagem.
Exemplo Básico de build
:
1
2
3
4
5
services:
app:
build:
context: ./app
dockerfile: Dockerfile
No exemplo acima:
context
: Define o diretório onde oDockerfile
e os arquivos da aplicação estão localizados. Neste caso, o contexto é./app
.dockerfile
: Especifica o nome doDockerfile
. Por padrão, o Compose espera um arquivo chamadoDockerfile
, mas você pode definir outros nomes.
Configuração de context
, dockerfile
e args
Além de context
e dockerfile
, é possível usar args
para definir variáveis de build, que podem ser acessadas dentro do Dockerfile
. Essas variáveis permitem que a imagem seja personalizada no momento da construção.
1. Contexto (context
) e Dockerfile
O context
define o diretório onde o Docker Compose buscará o Dockerfile
e os recursos necessários para construir a imagem.
Exemplo com Contexto e Dockerfile:
1
2
3
4
5
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.prod
2. Argumentos de Build (args
)
Os args
são variáveis passadas para o Dockerfile
durante o processo de construção. Eles são úteis para customizar a imagem de acordo com o ambiente ou com opções específicas de configuração.
Exemplo com args
:
1
2
3
4
5
6
7
services:
backend:
build:
context: ./backend
args:
NODE_ENV: production
API_KEY: my_secure_api_key
Neste exemplo:
NODE_ENV
eAPI_KEY
são passadas para o Docker durante o build e podem ser usadas noDockerfile
para ajustar a imagem de acordo com o ambiente.
Dockerfile Utilizando args
:
No Dockerfile
, você pode usar ARG
para declarar e acessar os argumentos de build.
1
2
3
4
5
6
7
8
9
# Dockerfile
FROM node:14
ARG NODE_ENV
ARG API_KEY
# Usando o argumento no build
ENV NODE_ENV=${NODE_ENV}
RUN echo "Building with API Key: ${API_KEY}"
Exemplo de Configuração para Construção de Imagens Personalizadas
Abaixo está um exemplo completo que mostra como usar o Docker Compose para construir uma aplicação web personalizada com diferentes ambientes (development
e production
), cada um com suas configurações específicas.
-
Arquivo
docker-compose.yml
:1 2 3 4 5 6 7 8 9 10 11 12 13 14
version: '3.8' services: web: build: context: ./web dockerfile: Dockerfile args: - NODE_ENV=production - API_URL=https://api.production.com ports: - "8080:80" environment: - NODE_ENV=production
-
Arquivo Dockerfile (
web/Dockerfile
):1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# Dockerfile para a aplicação web FROM node:14 # Argumentos de build ARG NODE_ENV ARG API_URL # Definindo variáveis de ambiente ENV NODE_ENV=${NODE_ENV} ENV REACT_APP_API_URL=${API_URL} WORKDIR /app COPY . . RUN npm install RUN npm run build CMD ["npm", "start"]
Explicação:
NODE_ENV
eAPI_URL
são argumentos de build usados para definir o ambiente e a URL da API.- Esses valores são passados do
docker-compose.yml
e, durante o build, são configurados no ambiente da aplicação.
-
Executando o Build com Docker Compose:
Para iniciar a construção e execução do serviço web, basta executar o comando:
1
docker-compose up --build
A opção
--build
força a recompilação da imagem sempre que o Compose é iniciado, aplicando novas configurações e mudanças no código.
Conclusão
Com o Docker Compose, é possível construir imagens personalizadas diretamente a partir do código-fonte, utilizando o Dockerfile
e argumentos de build para ajustar a imagem conforme o ambiente. No próximo capítulo, Escalando Serviços com Docker Compose, vamos explorar como escalar serviços para aumentar a capacidade de processamento, configurando múltiplas instâncias de containers para um único serviço.
10. Escalando Serviços com Docker Compose
Objetivo
Demonstrar como escalar serviços no Docker Compose de forma horizontal, ou seja, aumentando o número de instâncias (réplicas) de um serviço para melhorar o desempenho e atender a uma maior demanda.
Conteúdo
- Introdução ao Escalonamento de Serviços
- Como Escalar Serviços no Docker Compose
- Considerações de Rede e Balanceamento de Carga
- Exemplo Prático de Escalonamento com um Serviço Web
Introdução ao Escalonamento de Serviços
Escalonar serviços em Docker Compose permite criar múltiplas réplicas de um mesmo serviço, que rodam em containers separados. Isso é particularmente útil para:
- Aumentar a Capacidade de Processamento: Com mais instâncias, a aplicação pode atender a mais usuários simultaneamente.
- Redundância e Alta Disponibilidade: Se uma instância falha, outras continuam disponíveis para garantir a continuidade do serviço.
O Docker Compose facilita o escalonamento em ambientes de desenvolvimento e teste, enquanto em produção o Docker Swarm ou Kubernetes são normalmente usados para escalabilidade em larga escala.
Como Escalar Serviços no Docker Compose
Para escalar um serviço com o Docker Compose, você pode usar o comando docker-compose up
com a opção --scale
, ou especificar o parâmetro replicas
na configuração docker-compose.yml
.
1. Escalonando com o Comando --scale
O comando --scale
permite definir o número de instâncias para um serviço ao iniciar o Docker Compose.
Exemplo de Comando:
1
docker-compose up -d --scale web=3
Neste exemplo, o serviço web
será escalado para 3 instâncias (ou réplicas). Cada container será criado como uma nova instância do serviço, permitindo que eles compartilhem recursos e se comuniquem pela rede.
2. Configurando Réplicas no Arquivo docker-compose.yml
Se você estiver usando a versão 3 do Docker Compose com Docker Swarm, é possível definir o número de réplicas diretamente no docker-compose.yml
usando o parâmetro deploy
e replicas
.
Exemplo no docker-compose.yml
:
1
2
3
4
5
6
7
8
9
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
deploy:
replicas: 3
Neste exemplo, o serviço web
será escalado para 3 instâncias ao iniciar o Compose com Docker Swarm. Essa configuração é útil em ambientes de produção onde o Swarm é ativado para gerenciamento de clusters.
Nota: A opção
deploy
só é aplicável ao usar Docker Swarm. Em um ambiente Compose padrão, use--scale
diretamente no comandoup
.
Considerações de Rede e Balanceamento de Carga
Quando um serviço é escalado, cada instância (ou réplica) compartilha a mesma configuração de rede. No Docker Compose, as instâncias escaladas de um serviço podem se comunicar entre si usando o nome do serviço como hostname.
Por padrão, Docker Compose não configura um balanceador de carga, mas o Docker Swarm oferece balanceamento automático. Em um ambiente Docker Compose padrão, o balanceamento pode ser feito através de um proxy reverso como o Nginx ou o Traefik.
Configuração com Proxy Reverso
Usando o Nginx como proxy reverso, é possível distribuir o tráfego entre as instâncias de um serviço escalado. Isso requer a criação de um serviço de proxy separado, que distribui as requisições entre as réplicas.
Exemplo Prático de Escalonamento com um Serviço Web
Aqui está um exemplo de configuração docker-compose.yml
que escala um serviço web com múltiplas instâncias.
-
Arquivo
docker-compose.yml
:1 2 3 4 5 6 7 8 9
version: '3.8' services: web: image: nginx:alpine ports: - "8080:80" deploy: replicas: 3
-
Iniciar o Docker Compose com Escalonamento:
Para iniciar o serviço com escalonamento em Docker Compose, utilize o comando abaixo:
1
docker-compose up -d --scale web=3
Este comando cria três containers para o serviço
web
, distribuindo o tráfego entre as réplicas. -
Teste de Escalonamento:
Após iniciar o ambiente escalado, você pode verificar o status e as instâncias em execução com o comando:
1
docker-compose ps
Isso mostrará as instâncias escaladas do serviço
web
, listando cada container criado para atender ao serviço.
Conclusão
Escalar serviços no Docker Compose é uma prática poderosa que permite testar como uma aplicação se comporta com várias instâncias. Isso simula um ambiente de alta disponibilidade e maior capacidade de atendimento, especialmente útil em desenvolvimento e testes. No próximo capítulo, Saúde e Monitoramento de Containers com Healthchecks, exploraremos como configurar verificações de saúde (healthchecks) para monitorar o status de containers, garantindo que os serviços estejam sempre disponíveis.
11. Saúde e Monitoramento de Containers com Healthchecks
Objetivo
Aprender a configurar healthchecks no Docker Compose para monitorar o status de containers e garantir que os serviços estejam funcionando corretamente. Healthchecks são especialmente úteis para detectar e reiniciar containers em caso de falhas.
Conteúdo
- Introdução aos Healthchecks
- Configuração de Healthchecks no
docker-compose.yml
- Comandos, Intervalo e Retries
- Exemplo Prático de Healthcheck para um Banco de Dados e uma API
Introdução aos Healthchecks
Healthchecks são verificações automáticas que monitoram o estado de um container, executando comandos que retornam se o serviço está saudável ou falhou. Um container saudável está funcionando conforme o esperado, enquanto um container unhealthy pode exigir atenção, reinicialização ou correção.
Usando healthchecks no Docker Compose, você pode configurar:
- Comando a ser executado para verificar a saúde do container.
- Intervalo entre as verificações.
- Número de Tentativas antes de marcar o container como falho.
Configuração de Healthchecks no docker-compose.yml
No Docker Compose, você pode configurar um healthcheck para cada serviço dentro do docker-compose.yml
, especificando o comando de verificação, o intervalo entre tentativas, o tempo limite de execução e o número de tentativas antes de uma falha ser declarada.
Estrutura do Healthcheck
Aqui está uma estrutura básica de configuração de um healthcheck:
1
2
3
4
5
6
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 30s
Parâmetros do Healthcheck:
test
: Define o comando para verificar a saúde do container.interval
: Tempo entre as verificações consecutivas (ex.:1m30s
).timeout
: Tempo máximo para o comando de healthcheck ser executado antes de falhar.retries
: Número de tentativas antes de o container ser considerado comounhealthy
.start_period
: Tempo inicial para o container estar totalmente pronto antes do primeiro healthcheck ser executado.
Exemplo Prático de Healthcheck para um Banco de Dados e uma API
1. Healthcheck para um Banco de Dados MySQL
Aqui está uma configuração de healthcheck para um serviço de banco de dados MySQL, onde o comando verifica a conexão com o MySQL.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: '3.8'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 3
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Explicação:
- O comando
mysqladmin ping -h localhost
verifica se o MySQL está respondendo a conexões. - Intervalo: Verificação a cada 30 segundos.
- Timeout: Se o comando levar mais de 10 segundos, ele será considerado falho.
- Retries: Após 3 tentativas com falha consecutivas, o container é marcado como
unhealthy
.
2. Healthcheck para uma API Web
No caso de uma API Web, o healthcheck pode utilizar uma chamada HTTP para garantir que o servidor esteja respondendo. Abaixo está uma configuração de healthcheck para uma API em Node.js que responde em http://localhost:3000
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3.8'
services:
api:
build:
context: ./api
dockerfile: Dockerfile
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 1m
timeout: 5s
retries: 3
start_period: 30s
Explicação:
- Comando de Teste:
curl -f http://localhost:3000/health
verifica a resposta da API. A API deve ter um endpoint/health
que retorna um status positivo (200 OK) se tudo estiver correto. - Intervalo e Timeout: O healthcheck é executado a cada 1 minuto e falha se o comando leva mais de 5 segundos.
- Retries e Start Period: Após 3 tentativas consecutivas com falha, o container é considerado
unhealthy
. O período inicial (start_period
) de 30 segundos dá tempo para a API ser iniciada completamente antes da primeira verificação.
Monitorando o Status de Healthcheck
Após configurar e executar o Docker Compose, você pode monitorar o status de saúde dos containers com o comando docker ps
ou docker inspect
. Containers saudáveis mostrarão o status healthy
, enquanto containers com falha mostrarão unhealthy
.
1
2
docker-compose up -d
docker ps
A saída do comando docker ps
exibirá a coluna STATUS, indicando o estado atual (ex.: healthy
, unhealthy
) de cada container.
Conclusão
Com os healthchecks no Docker Compose, é possível monitorar o status de cada serviço de forma automática e responder rapidamente a problemas. Esta prática é crucial em ambientes de produção, onde a detecção de falhas e a recuperação rápida são essenciais para a estabilidade do sistema. No próximo capítulo, Usando Dependências de Inicialização e Ordem de Inicialização, vamos aprender como configurar dependências e garantir a ordem de inicialização dos containers para evitar problemas de conectividade entre serviços dependentes.
12. Usando Dependências de Inicialização e Ordem de Inicialização
Objetivo
Aprender a configurar dependências entre serviços no Docker Compose para garantir que os containers iniciem na ordem correta. Isso é essencial para aplicações onde certos serviços devem estar prontos antes que outros possam funcionar corretamente.
Conteúdo
- Importância da Ordem de Inicialização em Ambientes Multi-Containers
- Usando
depends_on
para Definir Dependências entre Containers - Limitações do
depends_on
e Soluções para Ordens de Inicialização Complexas - Exemplo Prático de Dependências com Banco de Dados e Serviço Web
Importância da Ordem de Inicialização em Ambientes Multi-Containers
Em ambientes multi-containers, alguns serviços dependem de outros para funcionar. Por exemplo, uma aplicação web pode depender de um banco de dados ou de uma API externa. Se o container de banco de dados não estiver pronto quando a aplicação web iniciar, a conexão pode falhar. Configurar a ordem de inicialização garante que os serviços dependentes só iniciem quando suas dependências estiverem disponíveis.
Usando depends_on
para Definir Dependências entre Containers
A diretiva depends_on
no Docker Compose permite definir uma ordem básica de dependência entre containers. Ao usar depends_on
, você informa ao Docker Compose que um serviço deve ser iniciado antes de outro, mas o depends_on
não garante que o serviço esteja pronto, apenas que seu container foi iniciado.
Exemplo com depends_on
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: '3.8'
services:
web:
image: nginx:alpine
depends_on:
- app
app:
image: myapp:latest
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example_password
Explicação:
- O serviço
web
depende do serviçoapp
, e o serviçoapp
depende do serviçodb
. - O Docker Compose iniciará os containers na ordem correta (
db
→app
→web
), masdepends_on
não verifica se odb
está pronto para receber conexões antes de iniciarapp
.
Limitações do depends_on
e Soluções para Ordens de Inicialização Complexas
O depends_on
define apenas a ordem de inicialização, sem verificar o status de saúde dos serviços. Em situações onde você precisa garantir que um serviço esteja totalmente pronto (por exemplo, com o banco de dados aceitando conexões), é melhor usar um healthcheck em conjunto com scripts de espera, como wait-for-it
, wait-for
ou dockerize
, que esperam até que um serviço específico esteja respondendo.
Exemplo de Script de Espera com wait-for-it
-
Adicionar o Script
wait-for-it
: Baixe o scriptwait-for-it.sh
e o adicione ao seu diretório de código. -
Configurar o Serviço para Esperar o Banco de Dados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
version: '3.8' services: app: image: myapp:latest depends_on: - db entrypoint: ["./wait-for-it.sh", "db:3306", "--", "npm", "start"] db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example_password healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 30s timeout: 10s retries: 5
Explicação:
- Healthcheck no Banco de Dados (
db
): Verifica se o banco de dados está pronto para aceitar conexões. entrypoint
no Serviçoapp
: Usa o scriptwait-for-it.sh
para aguardar até que o banco de dados esteja escutando na porta 3306 antes de iniciar a aplicação.
Esse exemplo garante que o app
não tente se conectar ao banco de dados antes que ele esteja pronto para aceitar conexões.
Exemplo Prático de Dependências com Banco de Dados e Serviço Web
Abaixo, apresentamos um exemplo mais completo que inclui um serviço web, um backend de aplicação, e um banco de dados. O backend espera o banco de dados estar pronto antes de iniciar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
depends_on:
- app
app:
build:
context: ./app
environment:
DATABASE_URL: mysql://user:password@db:3306/mydb
depends_on:
- db
entrypoint: ["./wait-for-it.sh", "db:3306", "--", "npm", "start"]
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example_password
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 5
Explicação:
- Serviço
db
: Inclui um healthcheck para verificar se o MySQL está ativo. - Serviço
app
: Usawait-for-it.sh
noentrypoint
para esperar o banco de dados (db
) estar pronto antes de iniciar. - Serviço
web
: Inicia somente após o backend (app
) estar em execução.
Esse exemplo garante que o banco de dados esteja totalmente funcional antes que o app
tente se conectar, e que o web
só seja acessado quando o backend estiver pronto.
Conclusão
A configuração de dependências e ordem de inicialização no Docker Compose é fundamental para aplicações com serviços interdependentes. Embora o depends_on
organize a sequência de inicialização, o uso de healthchecks e scripts de espera garante que os serviços dependentes estejam prontos antes de serem acessados, reduzindo falhas. No próximo capítulo, Práticas de Deploy em Produção com Docker Compose, exploraremos as melhores práticas para usar o Docker Compose em ambientes de produção, cobrindo configurações de segurança e performance.
13. Práticas de Deploy em Produção com Docker Compose
Objetivo
Explorar práticas recomendadas e configurações específicas para o uso do Docker Compose em produção, com foco em segurança, persistência e gerenciamento de logs para garantir a estabilidade e segurança dos serviços em ambientes reais.
Conteúdo
- Considerações para Uso em Produção
- Configurações Específicas para Produção
- Diferenças entre
docker-compose.yml
edocker-compose.prod.yml
- Configurações de Persistência e Logs
- Medidas de Segurança
- Diferenças entre
- Exemplo de Arquivo
docker-compose.prod.yml
para Produção
Considerações para Uso em Produção
Embora o Docker Compose seja amplamente usado para desenvolvimento e teste, ele pode ser adaptado para ambientes de produção em cenários mais simples. Para ambientes de produção de larga escala, recomenda-se o uso de ferramentas de orquestração como Kubernetes ou Docker Swarm, que oferecem funcionalidades avançadas, como escalonamento e balanceamento de carga.
Em produção com Docker Compose, é essencial ajustar as configurações para melhorar a segurança, garantir a persistência de dados e configurar logs adequados para monitoramento.
Configurações Específicas para Produção
1. Diferença entre docker-compose.yml
e docker-compose.prod.yml
Para separar configurações de desenvolvimento e produção, recomenda-se criar um arquivo específico para produção (docker-compose.prod.yml
). Este arquivo inclui apenas as diferenças de configuração específicas para o ambiente de produção.
Exemplo de Comando para Usar um Arquivo Específico:
1
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
2. Configurações de Persistência e Logs
Em produção, é importante garantir que os dados sejam persistentes e que os logs sejam configurados para análise e monitoramento.
- Persistência de Dados: Certifique-se de usar volumes para armazenar dados importantes, como bancos de dados, arquivos de configuração e logs. Isso evita a perda de dados ao reiniciar ou recriar containers.
- Gerenciamento de Logs: Configure a coleta de logs para análise e monitoramento contínuo, especialmente para detectar falhas e tendências de desempenho.
Exemplo de Configuração de Volume para Persistência:
1
2
3
4
5
6
7
8
services:
db:
image: postgres:13
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
3. Medidas de Segurança
Para garantir que o ambiente seja seguro, aplique as seguintes práticas de segurança:
- Usuário Não-Root: Defina um usuário não-root para rodar os containers, reduzindo o risco de exploração de vulnerabilidades.
- Variáveis de Ambiente Sensíveis: Utilize variáveis de ambiente ou arquivos
.env
para definir configurações sensíveis, como senhas e chaves de API, e mantenha esses arquivos fora do repositório de código. - Rede Isolada: Utilize redes isoladas para restringir a comunicação entre serviços, limitando o acesso de containers ao mínimo necessário.
Exemplo de Configuração Segura para Produção:
1
2
3
4
5
6
7
8
9
10
11
12
13
services:
app:
image: myapp:latest
user: "1001:1001" # Define um usuário não-root
environment:
- APP_ENV=production
- APP_DEBUG=false
networks:
- backend
networks:
backend:
driver: bridge
Exemplo de Arquivo docker-compose.prod.yml
para Produção
Aqui está um exemplo completo de um arquivo docker-compose.prod.yml
que aplica configurações de segurança e persistência, além de usar variáveis de ambiente para senhas e credenciais sensíveis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
networks:
- frontend
app:
image: myapp:latest
environment:
DATABASE_URL: mysql://user:password@db:3306/production_db
APP_ENV: production
depends_on:
- db
networks:
- frontend
- backend
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: secure_password
MYSQL_DATABASE: production_db
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 5
volumes:
db_data:
networks:
frontend:
driver: bridge
backend:
driver: bridge
Explicação do Exemplo:
- Segurança: Usuário não-root, variáveis de ambiente para senhas e configuração de redes isoladas.
- Persistência: Volume
db_data
para garantir a persistência dos dados do banco de dados. - Healthcheck: Monitoramento do serviço de banco de dados para detectar falhas rapidamente.
Executando o Compose com Arquivo de Produção
Para iniciar o ambiente em modo de produção usando os dois arquivos (docker-compose.yml
e docker-compose.prod.yml
), use o comando:
1
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Esse comando mescla as configurações do arquivo principal com o arquivo de produção, aplicando as configurações específicas do ambiente produtivo.
Conclusão
Configurar um ambiente de produção com Docker Compose requer ajustes para garantir persistência, segurança e monitoramento adequado. Separar as configurações de produção e desenvolvimento com arquivos docker-compose.prod.yml
permite uma maior flexibilidade e segurança. No próximo capítulo, Executando Comandos em Containers com Docker Compose, veremos como executar comandos específicos e tarefas em containers com o Compose, permitindo a administração e manutenção direta dos serviços.
14. Executando Comandos em Containers com Docker Compose
Objetivo
Demonstrar como executar comandos específicos e tarefas dentro de containers usando o Docker Compose, uma técnica útil para administração de serviços, inicialização de scripts e execução de comandos pontuais em containers.
Conteúdo
- Executando Comandos com
docker-compose run
- Executando Comandos com
docker-compose exec
- Exemplo Prático de Execução de Scripts e Comandos em Containers
Executando Comandos com docker-compose run
O comando docker-compose run
permite iniciar um novo container baseado em um serviço definido no arquivo docker-compose.yml
e executar um comando específico dentro dele. Este comando é útil para executar scripts de configuração ou comandos que devem ser executados uma única vez, como migrações de banco de dados ou tarefas de manutenção.
Sintaxe Básica:
1
docker-compose run <service> <command>
Exemplo:
1
docker-compose run app python manage.py migrate
Neste exemplo, o comando python manage.py migrate
é executado no serviço app
, que é iniciado temporariamente para rodar esse comando.
Nota: Como
docker-compose run
cria um novo container, ele não deve ser usado para comandos contínuos em containers já em execução.
Executando Comandos com docker-compose exec
O comando docker-compose exec
é usado para executar comandos em containers que já estão em execução. Isso é útil para acessar um container para diagnóstico ou para rodar comandos administrativos sem reiniciar o container.
Sintaxe Básica:
1
docker-compose exec <service> <command>
Exemplo:
1
docker-compose exec db mysql -u root -p
Neste exemplo, o comando mysql -u root -p
é executado dentro do container do serviço db
, permitindo acesso direto ao MySQL.
Nota: Diferente de
run
, o comandoexec
não cria um novo container, mas acessa um container que já está em execução.
Exemplo Prático de Execução de Scripts e Comandos em Containers
Aqui está um exemplo de como usar docker-compose run
e docker-compose exec
para tarefas comuns, como migração de banco de dados e execução de um script de inicialização.
1. Executando Migrações de Banco de Dados com run
Para rodar migrações de banco de dados em uma aplicação web, use docker-compose run
para iniciar o container e executar o comando de migração.
1
docker-compose run web python manage.py migrate
Neste exemplo:
- Serviço:
web
- Comando:
python manage.py migrate
, que executa as migrações do banco de dados no ambiente definido para o serviçoweb
.
2. Acessando um Container em Execução com exec
Para rodar comandos administrativos em um banco de dados MySQL que já está em execução, use docker-compose exec
.
1
docker-compose exec db mysql -u root -p
Aqui:
- Serviço:
db
- Comando:
mysql -u root -p
, que abre um shell interativo do MySQL dentro do containerdb
.
3. Executando Scripts de Inicialização
No arquivo docker-compose.yml
, é possível definir comandos específicos a serem executados durante a inicialização de um serviço usando a diretiva command
.
Exemplo no docker-compose.yml
:
1
2
3
4
5
6
services:
web:
image: myapp:latest
command: python manage.py runserver 0.0.0.0:8000
depends_on:
- db
Neste exemplo:
- O serviço
web
executa o comandopython manage.py runserver 0.0.0.0:8000
automaticamente ao ser iniciado, inicializando o servidor de desenvolvimento da aplicação.
Comparação entre docker-compose run
e docker-compose exec
Comando | Quando Usar | Exemplo |
---|---|---|
docker-compose run |
Para executar um comando em um novo container, especialmente para comandos que rodam uma única vez. | docker-compose run app python manage.py migrate |
docker-compose exec |
Para rodar comandos em containers que já estão em execução. Ideal para comandos administrativos e de debug. | docker-compose exec db mysql -u root -p |
Conclusão
Os comandos docker-compose run
e docker-compose exec
são ferramentas essenciais para administrar containers, permitindo a execução de comandos específicos e a realização de tarefas pontuais sem precisar modificar o ciclo de vida do container. No próximo capítulo, Troubleshooting e Solução de Problemas Comuns, abordaremos como diagnosticar e resolver problemas comuns em ambientes Docker Compose, com dicas para depuração e análise de logs.
15. Troubleshooting e Solução de Problemas Comuns
Objetivo
Identificar e resolver problemas comuns ao usar Docker Compose, com foco em técnicas de diagnóstico, uso de logs e comandos de inspeção para facilitar a solução de problemas que podem ocorrer em ambientes multi-containers.
Conteúdo
- Uso de Logs para Diagnóstico
- Comando
docker-compose logs
- Comando
- Diagnóstico de Problemas de Conexão e Rede
- Solução de Problemas de Persistência de Dados e Volumes
- Debug de Variáveis de Ambiente
- Comandos de Inspeção e Dicas Adicionais
Uso de Logs para Diagnóstico
O primeiro passo para diagnosticar problemas em Docker Compose é analisar os logs dos containers, pois eles fornecem informações detalhadas sobre a inicialização, execução e falhas dos serviços.
Comando docker-compose logs
O comando docker-compose logs
exibe os logs dos containers gerenciados pelo Compose. É possível ver todos os logs dos serviços ou apenas os logs de um serviço específico.
- Exibir Logs de Todos os Serviços:
1
docker-compose logs
- Exibir Logs de um Serviço Específico:
1
docker-compose logs app
- Seguir os Logs em Tempo Real:
1
docker-compose logs -f
Os logs podem revelar mensagens de erro, falhas de conexão e problemas de inicialização, ajudando a entender as causas das falhas.
Diagnóstico de Problemas de Conexão e Rede
Em ambientes multi-containers, problemas de rede são comuns. Algumas dicas para resolver problemas de comunicação entre containers incluem:
-
Verificar se os Containers Estão na Mesma Rede: Use o comando
docker network inspect <nome-da-rede>
para verificar se os containers envolvidos estão conectados à mesma rede.1
docker network inspect backend
-
Teste de Conexão entre Containers: Use o comando
docker-compose exec
para acessar um container e testar a conexão com outro usandoping
oucurl
.1
docker-compose exec app ping db
Se os containers não conseguirem se comunicar, verifique as configurações de rede no arquivo docker-compose.yml
para garantir que estejam usando a mesma rede.
Solução de Problemas de Persistência de Dados e Volumes
Problemas com volumes podem resultar em dados ausentes ou inconsistentes. Algumas práticas para resolver problemas de volumes incluem:
-
Verificar se o Volume Está Configurado: No
docker-compose.yml
, certifique-se de que os volumes foram definidos corretamente no nível global e também no serviço específico.1 2
volumes: db_data:
-
Remover e Recriar Volumes: Em alguns casos, pode ser necessário remover um volume para resolver problemas de dados corrompidos.
1 2
docker-compose down -v docker-compose up -d
Nota: Usar
down -v
remove todos os volumes, o que pode resultar em perda de dados. Use com cautela e certifique-se de fazer backup de dados importantes.
Debug de Variáveis de Ambiente
Problemas com variáveis de ambiente, como senhas e URLs incorretas, podem afetar o funcionamento dos serviços.
-
Verificar Variáveis de Ambiente no
.env
: Confirme que o arquivo.env
contém as variáveis necessárias e que elas estão definidas corretamente. -
Listar Variáveis de Ambiente de um Container: Use o comando
docker-compose exec <serviço> printenv
para listar todas as variáveis de ambiente definidas dentro de um container.1
docker-compose exec app printenv
Esse comando permite verificar se as variáveis foram carregadas corretamente no container e identificar possíveis erros de configuração.
Comandos de Inspeção e Dicas Adicionais
Vários comandos do Docker podem ajudar a inspecionar e diagnosticar problemas com containers e redes.
1. Inspecionar Containers
Use o comando docker inspect
para obter detalhes completos sobre um container específico, incluindo variáveis de ambiente, volumes e redes.
1
docker inspect <container_id>
2. Inspecionar Rede
Para verificar se todos os containers necessários estão conectados a uma rede, use o comando docker network inspect
.
1
docker network inspect backend
Este comando mostra informações detalhadas sobre os containers conectados à rede, ajudando a resolver problemas de conectividade.
3. Verificar o Status dos Containers
Use docker-compose ps
para verificar o status de cada container, incluindo se estão up
(em execução) ou exited
(finalizados).
1
docker-compose ps
Se um container estiver em estado exited
, execute docker-compose logs <serviço>
para identificar o motivo da falha.
Resumo de Comandos Úteis para Troubleshooting
Comando | Descrição |
---|---|
docker-compose logs |
Exibe os logs de todos os containers |
docker-compose exec app printenv |
Exibe as variáveis de ambiente de um container |
docker network inspect |
Inspeciona detalhes de uma rede |
docker inspect <container_id> |
Exibe detalhes completos sobre um container específico |
docker-compose ps |
Exibe o status dos containers gerenciados pelo Compose |
Conclusão
Com estas técnicas de troubleshooting e solução de problemas, você poderá identificar rapidamente problemas de configuração e execução em ambientes Docker Compose, garantindo que sua aplicação multi-containers funcione de forma estável e confiável. Este foi o último tópico do tutorial sobre Docker Compose!
Espero que este guia tenha sido útil e abrangente, cobrindo desde os fundamentos até práticas avançadas para gerenciar aplicações multi-containers de forma eficiente. Qualquer dúvida ou nova necessidade, estarei por aqui para ajudar!
Conclusão Geral
Ao longo deste tutorial, exploramos as principais funcionalidades e práticas recomendadas para o uso do Docker Compose, uma ferramenta que transforma a maneira de gerenciar aplicações multi-containers. Desde os conceitos básicos até configurações avançadas para produção, cada seção foi projetada para ajudá-lo a criar, escalar e monitorar seus containers de forma eficiente e segura.
O Docker Compose é uma solução poderosa para automatizar a infraestrutura de aplicações complexas, permitindo que os desenvolvedores concentrem seus esforços no desenvolvimento de recursos. Manter uma estrutura organizada e seguir as práticas recomendadas de configuração, persistência e segurança descritas aqui ajudará a garantir um ambiente estável e escalável para a sua aplicação. Seja em desenvolvimento ou produção, o Docker Compose permite um controle refinado e uma automação que impulsionam a produtividade e a confiabilidade.