इसे छोड़कर कंटेंट पर जाएं
Docs Try Aspire
Docs Try

Add Aspire to an existing app

यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है।

Add Aspire to the app you already have instead of rebuilding your solution around a new template. Start by choosing the AppHost style that fits your repo, then register the services, containers, shared infrastructure, and, when needed, custom executables you already run today, regardless of whether those workloads are written in C#, Node.js, Python, Go, Rust, Java, or something else.

As distributed applications grow, local development often turns into a collection of fragile scripts, copied connection strings, and startup-order tribal knowledge. Aspire gives you a single orchestration layer for the resources you already own. Define the relationships once in code, and Aspire handles service discovery, configuration injection, startup ordering, and dashboard visibility.

You can also adopt Aspire incrementally. Start by modeling the parts that are hardest to keep aligned by hand, such as containers, databases, caches, queues, background workers, and local dev commands. Add telemetry when you’re ready, then deepen the model as your app grows.

This guide is organized around the kinds of resources you already manage rather than around a preferred service language. Aspire is multi-language by design, so one AppHost can orchestrate a system that spans C#, Node.js, Python, Go, Rust, Java, and other supported workloads.

  • Existing services with hosting integrations: You already have C# services, Node.js apps, Vite frontends, Python apps, or ASGI apps such as FastAPI and want to use Aspire’s dedicated hosting APIs.
  • Existing containers and shared infrastructure: You already have images, Docker Compose files, databases, caches, queues, or reverse proxies that you want Aspire to coordinate.
  • Existing C# services: You already have C# projects or file-based C# apps and want the C# AppHost to orchestrate them directly.

In every scenario, you can choose either AppHost style and mix resource types in the same application model.

When a dedicated hosting API exists for a workload, prefer it over AddExecutable or addExecutable. Executable resources are the fallback for custom tools, one-off commands, or workloads that do not yet have a dedicated hosting integration.

The AppHost is the orchestration layer. Your choice here changes how you express orchestration, not what Aspire can orchestrate.

Use a C# AppHost when your repo already centers on C# or when you want a single-file orchestrator that still fits naturally into .NET SDK and IDE workflows.

  • Lives in a single apphost.cs file that uses #:sdk and #:package directives
  • Uses methods such as AddUvicornApp, AddPythonApp, AddNodeApp, AddViteApp, AddContainer, and AddCSharpApp
  • Fits naturally into existing .NET SDK, IDE, and repo workflows

Before you begin, make sure you have:

  • Aspire CLI installed
  • An existing application or workspace to add Aspire to
  • The runtimes and tools your existing services already need

For workloads with hosting integrations:

  • Service directories and standard project metadata for the workloads you plan to model, such as package.json, pyproject.toml, or requirements.txt
  • The runtimes and package managers those services already need

For custom executables as a fallback:

  • Working start commands for each service you plan to model
  • Any repo-local config files or working directories those commands rely on

For containers and shared infrastructure:

  • Existing image names, Dockerfiles, or Compose knowledge for the services you want to model
  • The databases, caches, queues, or reverse proxies you want Aspire to own or connect to

For C# services:

  • One or more C# projects or file-based C# apps if you plan to use AddCSharpApp
  • A solution file is optional and not required for a file-based C# AppHost

Adding Aspire to an existing app usually follows these steps:

  1. Choose an AppHost that fits your repo and workflow.
  2. Initialize Aspire support with aspire init.
  3. Register your existing processes, containers, and shared resources in the AppHost.
  4. Add telemetry and integrations where they add value.
  5. Run and verify the full system with Aspire orchestration.

The aspire init command creates the orchestration layer and helps wire the first set of resources into it.

  1. Navigate to the root of your existing repo:

    Navigate to your repo
    cd /path/to/your-repo
  2. Run aspire init:

    Initialize Aspire with a C# AppHost
    aspire init

    The command runs in interactive mode by default. It can detect existing C# projects, create a single-file AppHost, and add the initial package directives and configuration it needs.

For more details on the aspire init command and its options, see the CLI reference: aspire init.

After initialization, a typical C#-centric repo might look like this:

  • apphost.cs (new)
  • apphost.run.json (new)
  • Directoryservices/
    • DirectoryApi/
      • ExampleEcommerce.Api.csproj
    • DirectoryWeb/
      • package.json
      • Directorysrc/
  • Directoryworkers/
    • Directoryinventory-sync/
      • worker.py

Starter AppHost:

apphost.cs — Initial state
#:sdk Aspire.AppHost.Sdk@13.1.0
var builder = DistributedApplication.CreateBuilder(args);
// TODO: Add resources here
builder.Build().Run();

Add #:package directives in apphost.cs for the hosting integrations you use, such as Aspire.Hosting.Redis, Aspire.Hosting.Python, Aspire.Hosting.JavaScript, and Aspire.Hosting.PostgreSQL.

Once you have an AppHost, register the resources you already run today. Each service, container, integration, database, queue, project reference, or, when necessary, executable becomes a resource in the AppHost.

Two patterns stay the same across AppHost styles:

  • Use WithReference or withReference to declare resource dependencies and enable service discovery.
  • Use WaitFor or waitFor when one resource should wait for another to be ready.

Scenario: Existing services with hosting integrations

Section titled “Scenario: Existing services with hosting integrations”

Use this approach when your app includes supported service types such as Node.js apps, Vite frontends, Python scripts, or Uvicorn-based APIs. In these cases, prefer the dedicated hosting APIs over raw executable resources.

apphost.cs — Existing services with hosting integrations
#:sdk Aspire.AppHost.Sdk@13.1.0
#:package Aspire.Hosting.Redis@*
#:package Aspire.Hosting.Python@*
#:package Aspire.Hosting.JavaScript@*
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var api = builder.AddUvicornApp("api", "../services/api", "main:app")
.WithUv()
.WithReference(cache)
.WithExternalHttpEndpoints();
var worker = builder.AddPythonApp("worker", "../workers/inventory-sync", "worker.py")
.WithReference(cache);
var web = builder.AddViteApp("web", "../services/web")
.WithReference(api)
.WaitFor(api);
builder.Build().Run();

If a workload does not have a dedicated hosting API yet, use AddExecutable or addExecutable as the fallback path for custom CLIs, bespoke build tools, or unsupported runtime commands.

For first-class workload guidance, see JavaScript integration, Python integration, and Multi-language architecture.

Scenario: Existing containers and shared infrastructure

Section titled “Scenario: Existing containers and shared infrastructure”

Use this approach when you already have container images, Docker Compose services, or an infrastructure topology that you want to model directly in the AppHost.

Before you model shared infrastructure with Aspire, add the integrations you need:

Add hosting integrations
aspire add postgres
aspire add redis
apphost.cs — Existing containers and shared infrastructure
#:sdk Aspire.AppHost.Sdk@13.1.0
#:package Aspire.Hosting.PostgreSQL@*
#:package Aspire.Hosting.Redis@*
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("postgres")
.AddDatabase("orders");
var cache = builder.AddRedis("cache");
var api = builder.AddContainer("api", "ghcr.io/contoso/orders-api:latest")
.WithReference(db)
.WithReference(cache)
.WithHttpEndpoint(port: 8080, targetPort: 8080, name: "http");
var web = builder.AddContainer("web", "ghcr.io/contoso/orders-web:latest")
.WithReference(api)
.WithHttpEndpoint(port: 3000, targetPort: 3000, name: "http");
builder.Build().Run();

Use this approach when you want a file-based C# AppHost to orchestrate existing C# services without creating an AppHost .csproj and project-reference graph.

In a file-based C# AppHost, use AddCSharpApp to point at existing C# service paths directly. This works with single-file C# apps, directories, or existing .csproj files.

apphost.cs — Existing C# services
#:sdk Aspire.AppHost.Sdk@13.1.0
#:package Aspire.Hosting.Redis@*
#pragma warning disable ASPIRECSHARPAPPS001
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var api = builder.AddCSharpApp("api", "./src/Api/Store.Api.csproj")
.WithReference(cache)
.WithHttpHealthCheck("/health");
var worker = builder.AddCSharpApp("worker", "./src/Worker/Store.Worker.csproj")
.WithReference(cache);
builder.Build().Run();

Nothing requires a single pattern. It is common to keep some services as C# apps referenced from a file-based AppHost, run others with language-specific hosting APIs, and model shared infrastructure with integrations or containers in the same AppHost. A single application model can span C#, Node.js, Python, Go, Rust, Java, and containerized services side by side.

Telemetry is configured inside your workloads, not in the AppHost itself. The right setup depends on the service language you are bringing into Aspire.

If your app includes C# services, ServiceDefaults is the standard way to add observability, resilience, and health checks.

  1. Add ServiceDefaults if you did not enable it during aspire init:

    Add ServiceDefaults
    dotnet new aspire-servicedefaults -n YourProject.ServiceDefaults
    dotnet sln add YourProject.ServiceDefaults
    dotnet add YourProject reference YourProject.ServiceDefaults
  2. Update your service’s Program.cs:

    Program.cs — Add ServiceDefaults
    var builder = WebApplication.CreateBuilder(args);
    builder.AddServiceDefaults();
    var app = builder.Build();
    app.MapDefaultEndpoints();
    app.Run();

For more information, see Service Defaults.

If your app includes Node.js services, configure OpenTelemetry inside the service and point it at the Aspire OTLP endpoint.

  1. Install the OpenTelemetry packages:

    Install OpenTelemetry packages
    npm install @opentelemetry/api @opentelemetry/sdk-node \
    @opentelemetry/auto-instrumentations-node \
    @opentelemetry/exporter-trace-otlp-grpc \
    @opentelemetry/exporter-metrics-otlp-grpc
  2. Create a telemetry bootstrap file:

    telemetry.ts
    import { NodeSDK } from '@opentelemetry/sdk-node';
    import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
    const sdk = new NodeSDK({
    instrumentations: [getNodeAutoInstrumentations()],
    });
    sdk.start();
  3. Import it first in your app entry point:

    src/server.ts
    import './telemetry';
    import express from 'express';
    const app = express();

Use the OpenTelemetry SDK or instrumentation library that matches the runtime you are already using, then export telemetry to the OTLP endpoint Aspire provides during local orchestration.

Aspire integrations simplify common infrastructure such as Redis, PostgreSQL, RabbitMQ, and more. They are often the fastest way to make an existing setup easier to run because they replace copied connection strings and hand-managed startup order with explicit resource relationships. When you add an integration to the AppHost and reference it from dependent workloads, Aspire injects the configuration those workloads need.

  1. Identify the shared resources in your system, such as databases, caches, queues, or storage.
  2. Add the integration to the AppHost.
  3. Reference that resource from the apps that depend on it.
  4. Configure the client library inside each consuming service.

For example, to add Redis:

Add a Redis integration
aspire add redis
apphost.cs — Share Redis across existing workloads
#:sdk Aspire.AppHost.Sdk@13.1.0
#:package Aspire.Hosting.Redis@*
#:package Aspire.Hosting.Python@*
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var api = builder.AddContainer("api", "ghcr.io/contoso/api:latest")
.WithReference(cache)
.WithHttpEndpoint(port: 8080, targetPort: 8080, name: "http");
var worker = builder.AddPythonApp("worker", "../worker", "worker.py")
.WithReference(cache);
builder.Build().Run();

The client configuration stays inside each consuming service, whether that service is a C# project, container image, or executable launched by Aspire.

Add Redis client to a C# service
dotnet add YourApi package Aspire.StackExchange.Redis
Program.cs — Configure Redis in C#
var builder = WebApplication.CreateBuilder(args);
builder.AddRedisClient("cache");
Add Redis client to a Node.js project
npm install redis
Configure Redis in Node.js
import { createClient } from 'redis';
const client = createClient({
socket: {
host: process.env.CACHE_HOST,
port: Number(process.env.CACHE_PORT),
},
});

For concrete integration walkthroughs, see Redis integration, PostgreSQL integration, and RabbitMQ integration. Browse the full Integrations gallery for more options.

Once your AppHost models the system you want to run, start everything together with the Aspire CLI.

  1. From the directory that contains your AppHost, run:

    Run your application with Aspire
    aspire run
  2. Wait for the CLI to discover the AppHost, launch the resources, and print the dashboard URL.

    Example output
    Finding apphosts...
    Dashboard: https://localhost:17068/login?t=example
    Press CTRL+C to stop the apphost and exit.
  3. Open the dashboard in your browser and verify:

    • All resources start successfully
    • Service dependencies appear in the expected order
    • Logs, traces, and metrics are visible
    • Endpoints and environment variables look correct
  4. Exercise the actual app flows you care about, such as frontend-to-API calls, worker jobs, or database access.

  5. Stop the system by pressing ⌘+C Control + C Control + C in your terminal.

If you currently orchestrate the app with Docker Compose, the same relationships translate into an AppHost without forcing every workload to become a project resource.

docker-compose.yml
services:
postgres:
image: postgres:latest
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=mydb
ports:
- "5432:5432"
api:
build: ./api
environment:
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/mydb
depends_on:
- postgres
web:
build: ./web
environment:
- API_URL=http://api:8080
depends_on:
- api

After you have Aspire orchestrating the existing app, a few natural next steps are: