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.

Image description

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êiner MYSQL
  • 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:

Image description

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

  1. Defnir o ambiente necessário para sua aplicação funcionar utilizando um Dockerfile
  2. 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
  3. 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

👉🏻 Continuar leitura - Multi Stage Build

👉🏻 Continuar leitura - Criar e publicar imagem para MVC