Docker: minha Moby Dick - Parte IV
Até agora vimos como realizar pull de imagens dos registries, construir a imagem de uma aplicação por meio do Dockerfile e executar o contêiner que rodará nossa aplicação.
Mas tem um detalhe, no exemplo trabalhado tínhamos uma aplicação muito simples, que consistia basicamente em uma API com 4 endpoints. Contudo, na Devlândia, as aplicações são muito mais complexas e muitas vezes arquiteturadas como Microsserviços.
E, nesses casos, vamos subir todos os módulos e serviços em um único contêiner?
Pois, por boa prática, cada contêiner roda apenas um serviço, executando um único processo principal. Ou seja, assim como diz um clássico de 2011: "ado ado ado cada um no seu quadrado..."
Assim, se tivermos uma aplicação composta por vários processos específicos, como Banco de Dados, Gerenciador de Filas, Servidor Web e a aplicação em si, devemos conteinerizar cada processo separadamente.
Vish, carregá-los um-a-um, além de ser uma tarefa um pouquinho enfadonha, é também propensa a erros na sequência de inicializações, a esquecimento de um dos serviços e a parada ou a reinicialização de um ou mais serviços.
Mas, calma...o Docker tem a solução.
Para superarmos essa dificuldade podemos contar com uma criatura incrível: o Docker Compose.
O que é o Docker Compose?
O Docker Compose é uma ferramenta para definição e execução de múltiplos contêineres, a qual nos permite configurar todos os parâmetros necessários para execução de cada contêiner por meio de um arquivo de definição.
Dentro desse arquivo definimos cada contêiner como serviço e especificamos as portas expostas, as variáveis de ambiente, os volumes e redes, por exemplo. Ou seja, o arquivo de definição do Docker Compose especifica todo o ambiente: redes, volumes e serviços.
Tal arquivo é escrito utilizando-se o formato YAML e, por padrão, é nomeado docker-compose.yml.
Anatomia do docker-compose
Para quem não conhece, o padrão YAML utiliza a indentação como separador dos blocos de código das definições, sendo, portanto, essencial para a correta execução do docker-compose.
Cada linha desse arquivo pode ser definida como um par chave-valor ou uma lista.
1 version: '3'
2 services:
3 web:
4 build:
5 context: ./dir
6 dockerfile: Dockerfile-alternate
7 args:
8 versao: 1
9 ports:
10 - "5000:5000"
11 redis:
12 image: redis
Detalhadamente, na primeira linha do exemplo acima temos o par chave-valor, 'version', que define a versão do Docker Compose que utilizaremos, nesse caso, estamos usando a versão '3'.
No mesmo nível de indentação temos 'services', chave que define o início do bloco de serviços, os quais serão definidos no segundo nível de indentação.
No segundo nível de indentação temos o nome do primeiro serviço, nomeado como 'web', e, a partir dele, tudo que vier no próximo nível de indentação será definições referentes a ele.
No terceiro nível de indentação temos a chave 'build', que informa a forma de execução do serviço; nesse caso, o serviço 'web' será executado a partir da construção de uma imagem própria, sendo o 'build' equivalente ao comando 'docker build', visto anteriormente.
A seguir, no próximo nível de indentação, temos parametrização da construção da imagem.
Recomendados pelo LinkedIn
Voltando dois níveis de indentação, temos a definição das portas por meio da chave 'ports', o que equivale ao parâmetro '-p' do comando 'docker run'.
Subindo mais um nível saímos do bloco de definição do serviço 'web' e iniciamos um novo bloco de código para definição de outro serviço, nesse caso, nomeado 'redis'.
No próximo nível de indentação, temos a definição da imagem, por meio da chave 'image', que será usada para a construção do serviço 'redis', que será obtida do registry configurado no Docker Host, que, por padrão, é o hub.docker.com.
Executando o docker-compose
Agora que entendemos basicamente como criamos nosso docker-compose precisamos saber como gerenciá-lo.
Entre as opções para gerenciamento do docker-compose temos as seguintes que são as mais comuns:
'build': usada para construir todas as imagens dos serviços definidos no arquivo;
'up': usada para iniciar todos os serviços que estão definidos no docker-compose;
'stop': utilizada para parar todos os serviços definidos;
'ps': lista todos os serviços definidos no docker-compose.yml.
[Observação: nenhum serviço gerenciado pelo nosso docker-compose foi listado, pois no comando 'stop' encerramos a execução de todos eles.]
Subimos os serviços novamente (comando 'up') para demonstrarmos o comando 'ps'.
Por hoje, that's all, folks! Obrigada pela audiência e até o próximo episódio!
Cyber Security | CTF Player | AWS | Linux | SC-900 | FCP
1 aParabéns pelos artigos de Docker, muito bom ! Aguardo os próximos episódios… 🐳🐳🐳