Já faz algum tempo que publiquei um post contando sobre minha experiência com o .NET Aspire. Depois de mais de 14 semanas com .NET Aspire chegou a hora de dizer “até logo”.
Neste texto, vamos discutir a viabilidade de usar o .NET Aspire em projetos baseados em Docker Compose e também mostrar o processo de migração do .NET Aspire de volta para o Docker Compose.
Recapitulando
Em um post anterior, apresentei:
- Os componentes de produção e desenvolvimento.
- A relevância do dashboard do .NET Aspire, que resolve um grande problema no fluxo de trabalho de desenvolvimento.
- Como o Docker Compose e seu YAML quase não têm utilidade em produção (em cenários onde se usa Kubernetes).
O ponto alto do dashboard do .NET Aspire é o baixo consumo de recursos, o que possibilita o uso de Tracing, Log e métricas de forma integrada na experiência do desenvolvedor a um custo baixíssimo de consumo de recursos, menos de 60 megas em alguns casos.
Contudo, há um contraponto: quando trabalhamos com Kubernetes, o Docker Compose se torna menos relevante em produção. Mas e durante o desenvolvimento? E se realmente precisamos dos projetos .NET rodando em containers?
Abstraindo o uso de Containers
Um problema comum no ecossistema de desenvolvimento é a busca por abstrações que transformem o desenvolvedor em “mero digitador de código”. Em muitos casos, o dev quer:
- Ignorar Docker
- Ignorar Containers
- Ignorar Kubernetes
- Ignorar Observabilidade
- Ignorar Mensageria e a teoria de Filas/Streaming
Essa “fuga” costuma vir do desejo de “focar no negócio” e negligenciar detalhes técnicos. Embora isso, em um primeiro momento, possa deixar o cliente satisfeito, gera um cenário tende a se deteriorar no primeiro desafio.
Como os ciclos de vida dos desenvolvedores nas empresas são cada vez menores, muitos não ficam tempo suficiente para lidar com as consequências de decisões que tomaram. Acabam saindo da empresa antes e replicando as mesmas práticas ruins em novos lugares, como uma doença crônica silenciosa, que só é percebida quando já é tarde.
Quanto maior o nível de desconhecimento, maior a insegurança
É claro que precisamos nos adaptar aos novos tempos e trazer profissionais mais rapidamente para um nível sênior. Porém, experiência não se compra e, definitivamente, não se obtém com apenas seis meses de treinamento.
No Cloud Native .NET, por exemplo, já tive dificuldades ao trabalhar com desenvolvedores plenos. Eles normalmente não estão acostumados a tomar decisões arquiteturais ou a resolver problemas complexos sozinhos. Geralmente seguem soluções “enlatadas”, fornecidas pelos seniores. Essa falta de vivência real e prática pesa substancialmente.
Quando falamos de projetos baseados em containers, fazer tudo rodar em containers durante o desenvolvimento faz enorme diferença.
Aspire atrapalha ou ajuda?
TL;DR; Ajuda, mas o o orquestrador é o componente controverso.
A minha experiência com o .NET Aspire foi muito positiva. Trata-se de uma solução bem feita, entretanto cria um distanciamento perigoso entre o .NET e Containers.
🔴Orquestrador
O Orquestrador do .NET Aspire é embarcado na aplicação AppHost, que por sua vez exibe um Dashboard (que pode ser usado isolado).
Sobre o orquestrador, tenho 2 críticas:
- ou deveria substituir o Docker Compose permitindo aplicações .NET rodando em Containers com debug e toda a experiência que temos com Docker Compose no Visual Studio.
- ou ser substituído pelo Docker Compose
O que definitivamente não quero é que minhas aplicações .NET
que serão containers Linux,
sejam desenvolvidas sem containers Linux.
🔴Service Discovery
A implementação Service Discovery é útil se você estiver rodando suas aplicações .NET no Windows. Com cada API rodando em uma porta diferente no localhost
, ele se faz necessário e cumpre seu papel.
Mas na experiência com containers, onde cada container tem um nome, endereçável, e o mecanismo de service discovery é baseado em DNS, uma tecnologia de 1983, compatível com absolutamente qualquer coisa, essa implementação perde relevância e importância.
Então, no universo de containers, a implementação de Service Discovery do .NET Aspire é desnecessária.
🟢Open Telemetry
As configurações de Open Telemetry presentes em componentes e integrações do .NET Aspire são indiscutivelmente úteis e muito bem feitas. Não tenho do que reclamar, inclusive é algo que trouxe para o Docker Compose, com o dashboard.
🟢Dashboard
Se você já subiu ou tentou subir qualquer stack completa de observabilidade, provavelmente percebeu que o dashboard do .NET Aspire é um quebra-galho muito bom.
Eu vi na comunidade .NET um certo número de pessoas elogiando o Dashboard do .NET Aspire, como se fosse algo maravilhoso. Calma, né?! Pera lá. Seja Kibana ou Grafana, ou similares, temos opções mais profissionais, mais completas, mais flexíveis, desenhadas para cluster e produção, stateful, e mais customizáveis.
Dizer que o Dashboard do Aspire “é o que faltava” ou é o suficiente, é ridículo, uma demonstração absoluta de desconhecimento.
A grande carta na manga do Dashboard do .NET Aspire é:
- De um lado, ser um único componente que incorpora 4 responsabilidades (que demandariam 4 componentes):
- OpenTelemetry Collector
- Log
- Tracing
- Metrics
- E seu verdadeiro poder está no baixíssimo consumo de recursos.
O baixo consumo de recursos é o destaque, vezes mais relevante do que a quantidade de componentes que abstrai e vezes mais relevante que a simplicidade do dashboard.

🟢Containers auxiliares
O .NET Aspire também oferece praticidade na hora de adicionar containers auxiliares que administram serviços como Postgres, Redis etc. e configurá-los de forma integrada. Isso simplifica a adoção de ferramentas como PgWeb, PgAdmin ou Redis Commander, por exemplo.
Embora também sejam ferramentas que rodam sob containers, o distanciamento aqui não é muito relevante na medida que essas ferramentas que usamos para suportar o ambiente local, em geral, não serão as mesmas de produção. Dificilmente usaremos PgWeb, PgAdmin ou Redis Commander, em produção, portanto o distanciamento dessas configurações e containers é irrelevante.
🟢 Configurações de resiliência
Outro grande avanço são as configurações de resiliência e observabilidade automáticas entregues pelos componentes/integrações. Não poderia deixar de mencionar o acerto e quão bem-vindo foi.
O peso do distanciamento
É certo que não estamos aqui para aprender tecnologia, estamos aqui para entregar negócio com tecnologia. Aprender alguma tecnologia pode ser uma necessidade para entregar mais negócio, mas não é um objetivo em si.
Só não posso fechar os olhos sobre quão disruptivo é o universo Linux, para usuários nativos do Windows. O universo Cloud Native é desafiador principalmente para um desenvolvedor .NET , perder a possibildiade de debugar aplicações .NET containerizadas no linux é um problema.
Para quem é um problema?
Para mim, que sequer aprovo candidatos que não tenham conhecimento minimamente aprofundado em containers, quanto para alguns líderes que conversaram comigo nos últimos anos* e estão nessa jornada investindo em conhecimento para que seus times deixem de ser perdidos.
* Essas conversas nasceram quando
o docker-shim foi descontinuado ( Manchete: Kubernetes abandona docker)
e quando a docker criu sua subscription (Manchete: Docker agora é pago).


A lógica é simples: Músculo que não é usado atrofia!
Então, quando me distancio e vejo meu time (ou meus alunos) se distanciarem de containers, quase que fugindo do assunto, penso: Vamos nos enfraquecer essa “musculatura”!
E de fato a experiência de portar as configs do .NET Aspire para o Docker Compose me mostraram isso.
Container é algo disruptivo o suficiente para que eu possa julgar que não faz sentido nos distanciarmos, não é o que desejo para mim e para uma parcela talvez até pequena dos Arquitetos, Líderes Técnicos e CTO’s quem converso.
Porque no final do dia com .NET Aspire, não paramos de usar containers, só paramos de tocar neles no ambiente de desenvolvimento, com o Orquestrador do .NET Aspire colocamos uma camada de simplificação, entretanto os containers vão continuar dando problema em produção e agora cada vez mais porque o dev, agora com .NET ASPIRE, tem a chance de nunca “rodar” sua aplicação .NET em Containers Linux, diferente da experiência de quem usa Docker Compose.
A experiência entregue pelo .NET Aspire é útil, e talvez até vital, para uma galera mais jovem, atendendo uma demanda por devs cloud native produtivos a qualquer custo, onde Linux e Containers criam barreiras principalmente para haters do Linux.
Mas para aqueles que sofreram o suficiente com times perdidos, perder a possibilidade de rodar nossas aplicações .NET conteinerizadas no Linux significa aceitar a perda de autonomia, a perda da capacidade de execução, significa amarrar as nossas mãos.
Por outro lado, se quiséssemos alguma customização em um yaml, conseguiríamos obter referência de toda a comunidade Tech que usa docker no mundo. Com .NET Aspire, as customizações estão restritas aos projetos .NET com C#, ou seja, uma fração do mercado. O docker-compose.yaml, que poderia ser analisado no ambiente de desenvolvimento por qualquer time com o mínimo conhecimento de containers, dá lugar a um código C# que exige conhecimento muito mais específico.
Nos distanciamos das implantações.
Nos distanciamos drasticamente do Docker Compose e perdemos milhares de YAML’s produzidos por todas as comunidades, por todos os vendors e criadores de soluções conteinerizadas.

A lógica de deployment
O .NET Aspire tem no orquestrador todas as informações para que ambientes produtivos sejam criados a partir dele. Na hora de implantar, os utilitários do .NET Aspire geram deployments do Kubernetes, e serviços gerenciados dos principais cloud providers.

Isso faz com que eu me sinta quase como um gângster, forçando toda aplicação .NET Aspire a usar ou Kubernetes ou Serviços gerenciados de Cloud como se fossem as únicas opções, ignorando uma parcela significativa que continuará usando Swarm, Docker Compose on premise em servidores físicos ou virtuais, ou em VPS’s como uma parcela significativa dos MicroSaaS embrionários.
Quais desdobramentos possíveis?
Futurologia nunca foi meu departamento, mas não é muito difícil perceber que esse movimento distanciaria .NET do universo dos containers, ou pelo menos abraçaria aqueles que nunca iriam por conta da complexidade.
Então, são 2 pontos de vista antagônicos.
Um resultado previsível de uma adoção massiva do orquestrador do .NET Aspire é:
- Desaceleração na adoção de Docker, Docker Compose, Docker Swarm,
- Forçar a galera de On Premise e VPS para adotarem serviços de cloud gerenciados (com ou sem kubernetes).
- Retorno ao desenvolvimento de aplicações .NET rodando em Win32NT no IIS.

Claro que não é um bicho de 7 cabeças criar um provider para .NET Aspire para gerar Yaml de Docker Compose e afins, mas também não vejo sentido.
Mas o fato de não rodar .NET em containers, com a mesma experiência do docker compose, é um retrocesso indigesto.
Me recordo de ter torcido o nariz na época to Project Tye, agora torço o nariz para algumas decisões deliberadas a respeito de voltar com o workload inteiro para o Windows.
A discussão 6814 dá a pista de que pode ser que seja possível em um futuro qualquer, entretanto, enquanto não chega, vou usando o máximo do .NET Aspire no Docker Compose, já temos avanços incríveis com:
- Service Defaults
- Configurações de Telemetria.
- Configurações de Resiliência.
- Configurações de Service Discovery.
- Dashboard
- Se comportando como OpenTelemetry Collector
- Servindo Métricas
- Servindo Logs
- Servindo Tracing
Já é um imenso avanço.
Você pode me fazer um favor? É grátis!
Vote na issue #6814 do github
Essa issue conduz o pedido para que .NET ASPIRE suporte Containers Linux com a experiência de debug.
Essa atividade é fundamental para uma plena experiência cloud native.
Nunca te pedi nada!!

Bom o artigo. Bem esclarecedor, principalmente pra mim que ainda engatinho nesse mundo.