Verschiedenfarbige Programmiercode-Zeilen auf einem dunklen Bildschirm
Zurück zum Blog
aspirepythonjavascript

Aspire wird polyglott: Python, JavaScript, Go und TypeScript

Sven HennessenDevOps

Aspire hieß lange .NET Aspire – das ist Geschichte. Seit Version 13 sind Python, JavaScript, Go und Bun gleichberechtigte Sprachen im AppHost. Was das für heterogene Microservice-Landschaften bedeutet.

In Aspire 9 bedeutete "verteilte .NET-Anwendung" genau das: .NET. Python-Services, Node.js-Backends oder Go-Binaries ließen sich zwar als Container einbinden, aber ohne echte Integration – keine automatische Service Discovery, keine Verbindungsstring-Injektion, kein Debugging-Support. Ab Aspire 13 ist das anders.

Was "erster Klasse" bedeutet

Der Unterschied zwischen einem Container und einem first-class Service im AppHost ist nicht trivial. Ein Container läuft, mehr nicht. Ein first-class Service bekommt:

  • Automatische Verbindungsstrings – Referenzen werden als typisierte Umgebungsvariablen injiziert
  • Service Discovery – andere Services finden ihn über seinen Namen
  • Lokale Entwicklung ohne Docker – der Prozess startet direkt auf dem Host, mit dem nativen Runtime
  • Automatische Dockerfile-Generierung – für das Deployment
  • Dashboard-Integration – Logs und Traces erscheinen im Aspire Dashboard

Das gilt seit Aspire 13 für Python, JavaScript, Go und Bun.

Python

Python-Services werden über AddPythonApp eingebunden. Aspire erkennt automatisch, ob das Projekt uv, pip oder venv verwendet, und richtet die Laufzeitumgebung entsprechend ein:

var ml = builder.AddPythonApp("inference", "../Inference")
    .WithReference(db)
    .WithHttpEndpoint(port: 8000);

Für FastAPI- und Uvicorn-basierte Services gibt es AddUvicornApp:

var api = builder.AddUvicornApp("fastapi", "../FastApiService", "main:app")
    .WithReference(cache)
    .WithExternalHttpEndpoints();

Verbindungsstrings werden als Umgebungsvariablen übergeben, die Python-Seite liest sie wie gewohnt über os.environ. Das SSL-Zertifikat für HTTPS-Verbindungen zwischen Services wird automatisch als SSL_CERT_FILE gesetzt.

Aspire generiert beim aspire publish automatisch ein Dockerfile aus dem Python-Projekt – kein manuelles Schreiben nötig.

JavaScript und Node.js

AddJavaScriptApp ersetzt das frühere AddNpmApp und unterstützt npm, Yarn und pnpm – Erkennung erfolgt automatisch anhand der Lockfiles im Projektverzeichnis:

var frontend = builder.AddJavaScriptApp("frontend", "../Frontend", "npm run dev")
    .WithReference(api)
    .WithExternalHttpEndpoints();

Für Vite-basierte Frontends:

var frontend = builder.AddViteApp("frontend", "../Frontend")
    .WithReference(api);

Ab Aspire 13.4 ist Bun als Runtime verfügbar:

var worker = builder.AddBunApp("worker", "../Worker", "src/index.ts")
    .WithReference(queue);

Node-spezifisch: Das SSL-Zertifikat für interne HTTPS-Verbindungen wird als NODE_EXTRA_CA_CERTS injiziert, sodass fetch und HTTPS-Clients ohne zusätzliche Konfiguration gegen andere Aspire-Services kommunizieren können.

Go

Go-Support kam in Aspire 13.4 mit dem Paket Aspire.Hosting.Go:

var service = builder.AddGoApp("goservice", "../GoService")
    .WithReference(db)
    .WithHttpEndpoint(port: 8080);

In der lokalen Entwicklung startet Aspire den Service via go run. Debugging ist über den dlv-dap-Adapter für VS Code integriert. Für das Deployment generiert Aspire ein Dockerfile.

TypeScript AppHost – Orchestrierung ohne .NET

Wer eine Landschaft aus Python-, Node- und Go-Services orchestriert, braucht mit Aspire 13.4 kein .NET mehr im Toolchain des AppHost selbst. Der AppHost lässt sich vollständig in TypeScript schreiben:

import { createBuilder } from "@aspire/hosting";
import { addPostgres } from "@aspire/hosting-postgresql";
import { addPythonApp } from "@aspire/hosting-python";

const builder = await createBuilder(process.argv);

const db = addPostgres(builder, "db");
const inference = addPythonApp(builder, "inference", "../Inference")
    .withReference(db);
const frontend = builder.addJavaScriptApp("frontend", "../Frontend", "npm run dev")
    .withReference(inference);

await builder.build().run();

Die TypeScript-API spiegelt die C#-Oberfläche 1:1 – generiert aus denselben XML-Dokumentationskommentaren. Das bedeutet: wer die C#-API kennt, findet sich in der TypeScript-Version sofort zurecht.

Was noch in Entwicklung ist

Java ist als weiterer Deployment-Typ auf der Roadmap, aber noch nicht verfügbar. Rust ist diskutiert, aber nicht geplant. Die bestehenden Sprachen – Python, JavaScript, Go, TypeScript – sind in 13.4 als stabil einzustufen; Blazor WebAssembly ist noch als Preview markiert.

Bekannte Stolperfallen

TypeScript AppHost: Parameter ohne Default-Wert hängt CI-Pipelines

builder.addParameter('name') ohne expliziten Default-Wert blockiert aspire run in nicht-interaktiven Umgebungen – etwa in CI-Pipelines oder wenn stdin kein TTY ist. Der Prozess hängt ohne Fehlermeldung, ohne Timeout. Das ist besonders tückisch, weil es lokal mit einem Terminal-Fenster funktioniert.

// Hängt in CI:
const secret = await builder.addParameter('db-password');

// Korrekt: Default setzen
const secret = await builder.addParameter('db-password', { value: process.env.DB_PASSWORD ?? '' });

Das Issue (microsoft/aspire#17678) ist noch offen. Bis zur Lösung: Immer einen Default-Wert setzen, auch wenn er leer ist.

Python/JavaScript auf Kubernetes: PublishAsDockerFile löscht Container-Args

Wer für einen Uvicorn- oder JavaScript-Service einen PublishAsDockerFile-Callback hinzufügt – auch einen leeren –, verliert damit die generierten args im Helm-Manifest. Der Container startet dann ohne die konfigurierten Startparameter. Kein Fehler, kein Warning.

Das Aspire-Team hat das Issue mit silent-failure markiert (microsoft/aspire#16874). Workaround: Die args explizit im Callback setzen oder den Callback weglassen und stattdessen ein manuelles Dockerfile bereitstellen.

Brauchst du Unterstützung?

Du willst Python-, JavaScript- oder Go-Services in euren Aspire-AppHost integrieren, aber bist unsicher, wie ihr eine heterogene Microservice-Landschaft sauber orchestriert und deployt? Wir helfen dir gerne dabei! Melde dich einfach bei uns und wir schauen gemeinsam, wie wir euren polyglotten Stack mit Aspire aufsetzen.

Kontakt aufnehmen