Anteriormente, aprendemos aspectos importantes sobre imagens, volumes, redes, etc. O problema é que a combinação desses conceitos em uma abordagem onde cada passo é executado manualmente é um processo sujeito a erro, já que cada comando deve ser inserido corretamente e as etapas devem ser executadas na ordem correta. Para evitar esses problemas é que serve o Docker Compose.
O Docker Compose é uma ferramenta usada para escrever aplicaçãoes complexas e gerenciar os contêineres, as redes e os volumes que essa aplicação exigem para funcionar.
Ele simplifica o processo de configuração e execução de aplicativos para que você não precise digitar comandos complexos que podem levar a erros de configuração. É usado para descrever aplicações de forma consistente e previsível usando um arquivo de composição (extensão .yml) que contém detalhes de todos os volumes, redes e contêiners que compõem um aplicativo e os relacionamentos entre eles.
Docker Compose — Preparando nosso ambiente
Se você chegou aqui pelos seguindo os “artigos” anteriores, vimos que na abordagem manual usada até o momento, tínhamos feito:
- Criamos uma rede chamada
backend
- Criamos uma rede chamada
frontend
- Criamos um volume de dados em
MSQL
e um contêinerMYSQL
- Criamos um contêiner da aplicação
mvc1, mvc2, mvc3
com a definição do Dockerfile - Criamos também um contêiner de balanceador de carga com o
haproxy.cfg
Testamos utilizar o navegador e o fluxograma da junção de todas as nossas tecnologias ficou assim:
vamos limpar todas as nossas [imagens], [volumes], [redes] e [contêineres] criados em nosso ambiente. Vamos fazer todos os processos anteriores, só que dessa vez utilizando a tecnologia do Docker Compose.
Docker Compose — Roteiro Básico
- Defnir o ambiente necessário para sua aplicação funcionar utilizando um Dockerfile
- Criar o arquivo de composição (.yml) definindo quais são os serviços essenciais para a sua aplicação e o relacionamento entre eles
- Processo o arquivo de composição executando o comando
docker-compose
para que seu ambiente seja criado e configurado.
O Arquivo de composição (.yml ou yaml)
O arquivo de composição é o ponto de partida na utilização do Docker Compose. Embora seja possível colocar o arquivo de composição em qualquer local do projeto, por convenção, ele é colocado na raiz do diretório do projeto. Isso facilita o acesso e a organização.
YAML ou YML é um formato usado para cria arquivos de configuração de fácil leitura. Organizando os arquivos em seções e usa a identação com espaços para expressas a estrutura do arquivo.
version: "3"
volumes:
produtosdata:
networks:
frontend:
backend:
version
: Define a versão do Docker Compose que está sendo usada.
volumes
: Define volumes persistentes que podem ser usados pelos contêineres para armazenar dados de forma que, mesmo se o contêiner for removido, os dados não sejam perdidos.
networks
: Define redes personalizadas para que os contêineres possam se comunicar entre si.
Caso não tenha ficado claro como funciona os pontos definidos, você pode ler individualmente para que fique mais claro. volumes
, networks
.
Criando o arquivo de composição Docker-compose.yml
Como já foi estruturado a base anteriormente nosso arquivo docker-compose.yml
, vamos dar continuidade a sua estruturação.
volumes:
produtosdata:
networks:
frontend:
backend:
Explicando a seção Services
Agora surge uma nova seção chamada services
, que descreve os serviços usados para criar contêineres. A seção services
do arquivo docker-compose.yml
é onde definimos os serviços que compõem a nossa aplicação. Cada serviço nada mais é do que um contêiner que será criado e configurado automaticamente pelo Docker Compose.
Cada service
representa uma parte funcional da sua aplicação, como por exemplo:
- Um banco de dados (ex:
mysql
,postgres
) - Uma API backend (ex:
aspnet
,node
) - Um frontend (ex:
React
,Angular
,Razor Pages
) - Um balanceador de carga (ex:
haproxy
,nginx
) - Um cache (ex:
redis
,memcached
) - Entre outros serviços que rodam em contêineres
Comparando docker run
com docker-compose.yml
Docker Run
Como vimos anteriormente, podemos criar a imagem do MySQL com o comando:
docker container run -d
--name mysql
-v -produtosdata:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=numsey
-e bind-address=0.0.0.0
mysql:5.7
Rodando em Docker Compose
Agora, veja como tudo isso pode ser feito de forma mais organizada, legível e reutilizável usando o docker-compose.yml
:
volumes:
produtosdata:
networks:
frontend:
backend:
services:
mysql:
image: "mysql:5.7"
volumes:
- produtosdata:/var/lib/mysql
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=numsey
- bind-address=0.0.0.0
docker-compose build
Processar o arquivo de composição docker compose
e verificar sintaxe:
docker-compose build
docker-compose up
Processar o arquivo de composição docker compose
e iniciar aplicação
docker-compose up
Ao rodar o docker-compose up, a aplicação Docker gerará as instâncias configuradas pelo arquivo. Até o momento nossa aplicação está funcional, ainda precisamos definir outros serviços. Mas vamos dar uma olhada nos contêineres, volumes e networks até o momento?
docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c859974a3234 mysql:5.7 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 3306/tcp, 33060/tcp mvc1-mysql-1
docker network ls
NETWORK ID NAME DRIVER SCOPE
acdb16b2398f mvc1_backend bridge local
docker volume ls
DRIVER VOLUME NAME
local mvc1_produtosdata
Se você perceber, o Docker utiliza prefixos baseados no nome da pasta do projeto ou no nome especificado no arquivo docker-compose.yml
para garantir que os recursos, como containers, redes e volumes, não entrem em conflito entre diferentes projetos. Essa abordagem é útil quando você tem múltiplos projetos rodando em diferentes diretórios, mas com a mesma estrutura de nomes para containers, volumes ou redes.
Exemplo: Se o nome da pasta for mvc_project
, os containers criados a partir do docker-compose.yml
terão o prefixo mvc_project_
, como mvc_project_mysql_1
ou mvc_project_mvc_1
.
docker-compose down
Desfazer a operação, removendo contêineres e redes descritas no arquivo de composição
docker-compose down --volumes
Por padrão, o comando docker-compose down
não remove os volumes, pois eles armazenam dados persistentes dos containers. Usamos a opção --volumes
quando queremos também remover esses volumes e apagar completamente o ambiente.
Implementando serviço para contêiner da aplicação
Anteriormente definimos o serviço de MySQL, agora é necessário definir uma nova seção para nossa aplicação MVC. Para isso, vamos adicionar uma nova seção mvc
:
version: "3"
volumes:
produtosdata:
networks:
frontend:
backend:
services:
mysql:
image: "mysql:5.7"
volumes:
- produtosdata:/var/lib/mysql
- ./_MySQL_Init_Script:/docker-entrypoint-initdb.d
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=numsey
- bind-address=0.0.0.0
mvc:
build:
context: .
dockerfile: Dockerfile
networks:
- backend
- frontend
ports:
- 5000:80
environment:
- DBHOST=mysql
depends_on:
- mysql
-
build
Indica o início da seção build, que define como o Docker deve criar a imagem para o contêiner deste serviço.-
context
: Define o diretório do contexto que será usado para criar a imagem. Usa o diretório atual do projeto MVC. -
dockerfile
: Especifica o arquivo Dockerfile usado para criar a imagem.
-
-
networks
: Especifica as redes com as quais o container vai se conectar.-
backend
: acessar o container do mysql -
frontend
: receber as requisições
-
-
ports
: Define o mapeamento das portas. -
DBHOST
: Define o nome do host. -
depends_on
: Indica a ordem na qual os contêineres serão criados. Aqui, o contêiner mysql será iniciado antes do contêiner mvc.
Desse modo, nossa aplicação já tem dois container a ser utilizado. mysql
e MVC
.
[+] Running 5/5
✔ Network mvc1_backend Created 0.0s
✔ Network mvc1_frontend Created 0.0s
✔ Volume "mvc1_produtosdata" Created 0.0s
✔ Container mvc1-mysql-1 Started 0.5s
✔ Container mvc1-mvc-1 Started
Se você analisar o logs com o comando docker-compose logs
, irá ver que além do container de MySQL, agora existe o da nossa aplicação MVC
. Agora é só acessar a aplicação e você verá que estará funcionando corretamente.
você pode remover os containers com o comando, (se quiser remover os volumes acrescente o -v):
docker-compose rm -s