Do docker-compose ao diagrama: a história do compose-diagrams

Por Jalves Nicacio
Do docker-compose ao diagrama: a história do compose-diagrams

Um problema que todo mundo já viu

Abra um artigo técnico sobre um sistema distribuído e procure o diagrama de arquitetura. Quase sempre ele está lá: caixas, setas, um cilindro para o banco de dados. E quase sempre foi desenhado à mão, numa ferramenta genérica, com uma notação que só o autor conhece.

A ferramenta que apresento neste texto nasceu de uma discussão em uma disciplina do meu doutorado. Partimos da constatação de que os profissionais costumam usar diagramas informais para representar os componentes de um sistema. Notações como UML aparecem mais em contextos acadêmicos ou em documentos que formalizam modelos de software, e o C4, mais informal, vem ganhando espaço entre profissionais. No dia a dia, porém, o que domina é o diagrama ad-hoc.

O diagrama ad-hoc tem dois defeitos. Ele não segue regra nenhuma, então cada leitor precisa adivinhar o que uma seta significa. E ele envelhece: o sistema muda, o desenho fica, e depois de algum tempo os dois contam histórias diferentes.

A ideia: o sistema já se descreve

A saída que surgiu naquela discussão foi parar de desenhar e passar a gerar. Um sistema distribuído moderno já carrega artefatos que descrevem como ele é implantado. Um arquivo docker-compose.yaml diz quais serviços existem, que imagem cada um roda, quais portas publica, de quem depende e onde guarda dados.

Chamamos esses artefatos de descritores do sistema. Eles têm uma qualidade que nenhum desenho tem: são usados para subir o sistema de verdade, então não podem ficar desatualizados sem que alguém perceba.

Se o diagrama é gerado a partir do descritor, ele herda essa qualidade. Mudou o arquivo, mudou o diagrama. A consistência deixa de depender da disciplina de quem desenha.

Do protótipo ao artigo

Iniciamos o projeto em junho de 2020. Naquele momento, era um protótipo em Python chamado DAD, de Descriptor to Architectural Diagrams, cujo objetivo era provar que era possível gerar um diagrama arquitetural a partir do docker-compose (prova de conceito). Ele lia um docker-compose e desenhava os serviços, as dependências e os volumes com a biblioteca Diagrams, que cria diagramas a partir de código. Mostrar que era possível gerar o diagrama, porém, era só o primeiro passo. A questão que nos interessava era outra: esse diagrama, gerado a partir do descritor do sistema, é mais consistente com o sistema do que um diagrama ad-hoc?

Em 2021 essa questão virou artigo. Nós publicamos Towards improving architectural diagram consistency using system descriptors na 29th IEEE/ACM International Conference on Program Comprehension (ICPC 2021). O texto também está no arXiv.

O artigo propõe duas hipóteses: um diagrama gerado a partir de um descritor válido é consistente, e um descritor válido gerado a partir de um diagrama também é. No estudo de caso, escrevemos um descritor a partir do diagrama de implantação da Netflix e geramos um diagrama novo. Todos os elementos do docker-compose puderam ser representados, e o diagrama gerado não tinha as inconsistências do original.

Em 2022 demos continuidade à pesquisa com An approach to build consistent software architecture diagrams using DevOps system descriptors, publicado nos Companion Proceedings da ACM/IEEE 25th International Conference on Model Driven Engineering Languages and Systems (MODELS ’22). Esse segundo artigo traz diretrizes para criar diagramas, uma taxonomia dos conceitos presentes nos descritores e um processo para convertê-los em diagramas, aplicado a um sistema de newsfeed descrito em Docker Compose. A conclusão foi cautelosa: os descritores ainda levam a diagramas consistentes só até certo ponto, mas a abordagem é promissora. O texto também está no arXiv.

Nesse período, a pesquisa se voltou para um questionário com profissionais de engenharia de software. Mostramos a eles alguns diagramas arquiteturais e perguntamos sobre os pontos fortes e fracos dos que eram gerados a partir de descritores. O código, porém, ficou parado: o último commit daquela fase é de maio de 2021.

A retomada: compose-diagrams

Em 2026 retomei o projeto, agora com o nome compose-diagrams. O protótipo tinha o arquivo de entrada fixo no código; a versão atual é uma ferramenta que qualquer pessoa instala e usa. São três novidades.

Linha de comando. Um comando recebe o docker-compose e devolve a imagem, em PNG, SVG, PDF ou JPG, com a direção do layout que você escolher.

Interface web local. Uma página com o arquivo à esquerda e o diagrama à direita, redesenhado enquanto você edita. Ela roda na sua máquina, e o arquivo não é enviado a lugar nenhum.

Estilo C4. Esta é a novidade que mais conversa com a discussão original. Além do diagrama com ícones, a ferramenta gera a visão de contêineres do C4: o projeto compose é a fronteira do sistema, cada serviço é um contêiner com sua imagem e suas portas, bancos e volumes nomeados são bases de dados, e as dependências viram relações rotuladas. O leitor recebe uma notação que já conhece, em vez de mais um desenho ad-hoc.

As duas figuras abaixo vêm do mesmo arquivo, um exemplo com MySQL, PostgreSQL, Kafka e Zookeeper. A primeira é o estilo de ícones, a segunda é o C4.

Figura 1. Estilo ad-hoc: serviços, dependências e volumes com ícones

Figura 2. Estilo C4: visão de contêineres do mesmo sistema

Como experimentar

Você precisa de Python 3.9 ou mais novo e do Graphviz instalados. Depois:

git clone https://github.com/jalvesnicacio/compose-diagrams.git
cd compose-diagrams
python3 -m venv .venv
source .venv/bin/activate
pip install .

Para gerar um diagrama a partir de um arquivo, no estilo de ícones e no estilo C4:

compose-diagrams docker-compose.yaml
compose-diagrams docker-compose.yaml -s c4 -o arquitetura.svg

Para abrir a interface web no navegador:

compose-diagrams --web

O repositório traz arquivos de exemplo na pasta docker-compose-files, se você quiser testar antes de usar um seu.

Se você prefere não instalar Python nem Graphviz, dá para usar Docker. Na pasta do projeto, construa a imagem e suba a interface web, que fica em http://localhost:8000:

docker build -t compose-diagrams .
docker run --rm -p 8000:8000 compose-diagrams

A mesma imagem serve para a linha de comando. Basta montar a pasta onde está o seu arquivo, e o diagrama é gravado nela:

docker run --rm -v "$PWD":/work compose-diagrams docker-compose.yaml -o diagrama.png

O que vem a seguir

O projeto é aberto e está longe de pronto. As pendências estão registradas como issues no GitHub, e algumas são boas portas de entrada para quem quiser contribuir:

  • arquivos grandes ainda geram diagramas largos demais;
  • o estilo de ícones usa o mesmo ícone de servidor para tudo, quando poderia mostrar o do MySQL, do Redis ou do Kafka;
  • as redes do docker-compose são lidas, mas ainda não são desenhadas;
  • falta publicar o pacote no PyPI e a imagem Docker num registro, para instalar sem clonar o repositório.

Há também perguntas em aberto sobre o C4. O docker-compose não diz quem usa o sistema nem com que sistemas externos ele conversa, e essas são peças centrais de um diagrama C4. Como representá-las sem inventar informação é uma discussão que eu gostaria de ter com quem usa a notação no dia a dia.

No mesmo dia em que as issues foram abertas, chegaram duas contribuições externas, de pessoas diferentes. A primeira veio minutos depois da issue correspondente, e as duas já estão incorporadas ao projeto. Se o problema dos diagramas desatualizados também incomoda você, o repositório está aberto.