Compose: orquestração de aplicações em contentores Docker
O Compose automatiza a gestão de contentores, facilitando assim o dimensionamento e a implementação de aplicações no Docker. Neste tutorial, analisamos em profundidade a configuração e a utilização do Docker Compose para que possa aplicá-lo no seu próprio ambiente de produção.
O que é o Docker Compose?
O Docker Compose é utilizado para gerir aplicações e aumentar a eficiência no desenvolvimento de contentores. A configuração é guardada num único ficheiro YAML, o que permite criar e escalar aplicações facilmente. O Docker Compose é frequentemente utilizado para configurar um ambiente local, mas também pode fazer parte de um fluxo de trabalho de integração contínua/entrega contínua (CI/CD). Os programadores podem definir uma versão específica de contentores para testes ou para uma fase específica do pipeline. Isto facilita a identificação de problemas e a correção de erros antes que estes cheguem à produção.
Docker Compose: eis os requisitos
Para a orquestração de contentores, é necessário ter tanto o Docker Engine como o Docker Compose. Por conseguinte, deve ter uma das seguintes opções configuradas no seu sistema:
- Docker Engine e Docker Compose: podem ser instalados como binários independentes
- Docker Desktop: ambiente de desenvolvimento com interface gráfica de utilizador que inclui o Docker Engine e o Docker Compose
Nos nossos guias, pode aprender a instalar o Docker Compose em diferentes sistemas operativos:
Guia passo a passo: como utilizar o Docker Compose
Para te mostrar os conceitos do Docker Compose, vamos utilizar uma aplicação web simples em Python que inclui um contador de pedidos. Para tal, recorremos ao framework Python Flask e à base de dados em memória Redis (também conhecida como In-Memory Database). Não vais precisar de instalar o Python nem o Redis, uma vez que os terás à disposição como imagens do Docker.
Passo 1. Criar os ficheiros do projeto
Abra o terminal e crie uma nova pasta para o projeto.
$ mkdir composedemoshellEm seguida, aceda à pasta que acabou de criar.
$ cd composedemoshellCrie o ficheiro app.py na pasta e insira o seguinte código:
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I was here {} times.\n'.format(count)pythonEstamos a utilizar «redis» como nome de host e a porta «6379» como porta predefinida. Além disso, especificámos que a função get_hit_count() deve tentar ligar-se ao serviço várias vezes. Esta é a prática recomendada, uma vez que o Redis pode não estar disponível logo após o arranque da aplicação ou pode apresentar problemas de ligação durante a sua execução.
Crie também o ficheiro requirements.txt com as dependências necessárias:
flask
redisplaintextPasso 2. Configurar o Dockerfile
O Dockerfile é utilizado para criar a imagem do Docker. É aqui que se especificam todas as dependências necessárias à aplicação Python.
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]shellO Dockerfile indica ao Docker para utilizar a imagem Python 3.7. Também definimos as variáveis de ambiente para o comando flask. Com apk add, estamos a instalar o gcc e outras dependências. Com EXPOSE, estamos a indicar que o contentor deve monitorizar a porta 5000. Com COPY, copiamos o conteúdo da pasta atual para o diretório de trabalho /code. Por fim, definimos flask run como comando padrão para o contentor.
Verifique se o ficheiro Dockerfile foi guardado sem extensão, uma vez que alguns editores adicionam automaticamente o sufixo .txt.
Passo 3. Criar o ficheiro YAML
Configuramos os serviços «redis» e «web» no ficheiro docker-compose.yml.
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"yamlO serviço «web» utiliza a imagem criada pelo Dockerfile e liga o contentor ao computador anfitrião através da porta 8000, enquanto o servidor web Flask é executado na porta 5000. Por outro lado, a imagem do Redis é obtida diretamente do repositório oficial do Docker Hub.
Passo 4. Executar a aplicação com o Compose
Inicie a aplicação a partir da pasta do seu projeto.
docker compose upshellAbra o seu navegador e aceda a http://localhost:8000 ou http://127.0.0.1:8000; ambas as opções servem.
Deve ver a seguinte mensagem:

Atualize a página. O número de visitas deverá aumentar de 1 em 1.

Encerre a aplicação com o seguinte comando:
$ docker compose downshellTambém podes premir Ctrl + C no terminal onde iniciaste a aplicação.
Passo 5. Adicionar uma ligação de montagem
Se quiseres adicionar um Bind Mount ao serviço web, podes fazê-lo no ficheiro docker-compose.yml.
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
environment:
FLASK_DEBUG: "true"
redis:
image: "redis:alpine"yamlNa secção «volumes», especificamos que a pasta do projeto atual deve ser montada no diretório /code dentro do contentor. Isto permite-lhe modificar o código sem necessidade de recompilar a imagem. A variável de ambiente FLASK_DEBUG garante que flask run seja executado em modo de depuração.
Passo 6. Recriar e executar a aplicação
Introduza o seguinte comando no terminal para reconstruir o ficheiro Compose:
docker compose upshellPasso 7. Atualizar a aplicação
Agora que está a utilizar um Bind Mount na sua aplicação, pode alterar o seu código e ver as alterações automaticamente, sem ter de recompilar a imagem.
Adicione uma nova linha de saudação no ficheiro app.py.
return 'Hello from Docker! I was here {} times.\n'.format(count)pythonAtualize o navegador para verificar se as alterações foram aplicadas corretamente.

Passo 8. Outros comandos
A opção --help apresenta uma lista dos comandos disponíveis para o Docker Compose:
docker compose --helpshellPodes adicionar o argumento -d para executar o Docker Compose em segundo plano:
docker compose up -dshellCom down, todos os contentores são eliminados. A opção --volumes também elimina os volumes utilizados pelo contentor Redis.
docker compose down --volumesshell