Skip to content
Docs Try Aspire
Docker logo

The Aspire Docker hosting integration enables you to deploy your Aspire applications using Docker Compose. This integration models Docker Compose environments as compute resources that can host your application services. When you use this integration, Aspire generates Docker Compose files that define all the services, networks, and volumes needed to run your application in a containerized environment. It supports:

  • Generating Docker Compose files from your app model for deployment
  • Orchestrating multiple services, including an Aspire dashboard for telemetry visualization
  • Configuring environment variables and service dependencies
  • Managing container networking and service discovery

The Docker hosting integration is available in the 📦 Aspire.Hosting.Docker NuGet package:

Aspire CLI — Add Aspire.Hosting.Docker package
aspire add docker

The Aspire CLI is interactive, be sure to select the appropriate search result when prompted:

Aspire CLI — Example output prompt
Select an integration to add:
> docker (Aspire.Hosting.Docker)
> Other results listed as selectable options...

The following example demonstrates how to add a Docker Compose environment to your app model using the AddDockerComposeEnvironment method:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var compose = builder.AddDockerComposeEnvironment("compose");
var cache = builder.AddRedis("cache")
.PublishAsDockerComposeService();
var api = builder.AddProject<Projects.Api>("api")
.WithReference(cache)
.PublishAsDockerComposeService();
var web = builder.AddProject<Projects.Web>("web")
.WithReference(cache)
.WithReference(api)
.PublishAsDockerComposeService();
builder.Build().Run();

The preceding code:

  • Creates a Docker Compose environment named compose
  • Adds a Redis cache service that will be included in the Docker Compose deployment
  • Adds an API service project that will be containerized and included in the deployment
  • Adds a web application that references both the cache and API service
  • Configures all services to be published as Docker Compose services using PublishAsDockerComposeService

Add Docker Compose environment resource with properties

Section titled “Add Docker Compose environment resource with properties”

You can configure various properties of the Docker Compose environment using the WithProperties method:

builder.AddDockerComposeEnvironment("compose")
.WithProperties(env =>
{
env.DashboardEnabled = true;
});

The DashboardEnabled property determines whether to include an Aspire dashboard for telemetry visualization in this environment.

Add Docker Compose environment resource with compose file

Section titled “Add Docker Compose environment resource with compose file”

You can customize the generated Docker Compose file using the ConfigureComposeFile method:

builder.AddDockerComposeEnvironment("compose")
.ConfigureComposeFile(composeFile =>
{
composeFile.Networks.Add("custom-network", new()
{
Driver = "bridge"
});
});

Add Aspire dashboard resource to environment

Section titled “Add Aspire dashboard resource to environment”

The Docker hosting integration includes an Aspire dashboard for telemetry visualization. You can configure or disable it using the WithDashboard method:

// Enable dashboard with custom configuration
builder.AddDockerComposeEnvironment("compose")
.WithDashboard(dashboard =>
{
dashboard.WithHostPort(8080)
.WithForwardedHeaders(enabled: true);
});
// Disable dashboard
builder.AddDockerComposeEnvironment("compose")
.WithDashboard(enabled: false);

The WithHostPort method configures the port used to access the Aspire dashboard from a browser. The WithForwardedHeaders method enables forwarded headers processing when the dashboard is accessed through a reverse proxy or load balancer.

Aspire provides a progressive deployment workflow for Docker Compose, allowing you to publish, prepare environments, and deploy in separate steps or all at once.

To generate Docker Compose files and artifacts without building container images, use the aspire publish command:

Terminal window
aspire publish

This command:

  • Generates a docker-compose.yaml from the app host
  • Generates a .env file with expected parameters (unfilled)
  • Outputs everything to the aspire-output directory

Step 2: Prepare Environment Configurations

Section titled “Step 2: Prepare Environment Configurations”

To prepare environment-specific configurations and build container images, use the aspire do prepare-{resource-name} command, where {resouce-name} is the name of the Docker Compose environment resource:

Terminal window
# For staging environment
aspire do prepare-compose --environment staging
# For production environment
aspire do prepare-compose --environment production

These commands:

  • Generate a docker-compose.yaml from the app host
  • Generate environment-specific .env files with filled-in values
  • Generate container images
  • Outputs everything to the aspire-output directory

To perform the complete deployment workflow in one step, use the aspire deploy command:

Terminal window
aspire deploy

This command:

  • Generates a docker-compose.yaml from the app host
  • Generates environment-specific .env files with filled-in values
  • Generates container images
  • Outputs everything to the aspire-output directory
  • Runs docker compose up against the generated files

To clean up a running Docker Compose deployment, use the aspire do docker-compose-down-{resource-name} command:

Terminal window
aspire do docker-compose-down-compose

This command stops and removes all containers, networks, and volumes created by the Docker Compose deployment.

The Docker hosting integration captures environment variables from your app model and includes them in a .env file. This ensures that all configuration is properly passed to the containerized services.

For advanced scenarios, use ConfigureEnvFile to customize the generated .env file:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddDockerComposeEnvironment("compose")
.ConfigureEnvFile(env =>
{
env["CUSTOM_VAR"] = new CapturedEnvironmentVariable
{
Name = "CUSTOM_VAR",
DefaultValue = "my-value"
};
});

This is useful when you need to add custom environment variables to the generated .env file or modify how environment variables are captured.

When deploying containers, you can customize how container images are named and tagged when pushed to a registry. This is useful when you need to:

  • Use different image names for different environments
  • Apply custom tagging strategies (e.g., semantic versioning, Git commit hashes)
  • Push to different registries or namespaces

Use WithRemoteImageName and WithRemoteImageTag to customize the image reference:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddProject<Projects.Api>("api")
.PublishAsDockerComposeService()
.WithRemoteImageName("myorg/myapi")
.WithRemoteImageTag("v1.0.0");
// After adding all resources, run the app...

For more complex scenarios, use WithImagePushOptions to register a callback that can dynamically configure push options:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddProject<Projects.Api>("api")
.PublishAsDockerComposeService()
.WithImagePushOptions(context =>
{
// Customize the image name based on the resource
// Note: Ensure resource names are valid for container image names
var imageName = context.Resource.Name.ToLowerInvariant();
context.Options.RemoteImageName = $"myorg/{imageName}";
// Apply a custom tag based on environment or version
var version = Environment.GetEnvironmentVariable("APP_VERSION") ?? "latest";
context.Options.RemoteImageTag = version;
});
// After adding all resources, run the app...

For asynchronous operations (such as retrieving configuration from external sources), use the async overload:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddProject<Projects.Api>("api")
.PublishAsDockerComposeService()
.WithImagePushOptions(async context =>
{
// Retrieve configuration asynchronously
var config = await LoadConfigurationAsync();
context.Options.RemoteImageName = config.ImageName;
context.Options.RemoteImageTag = config.ImageTag;
});
// After adding all resources, run the app...

Multiple callbacks can be registered on the same resource, and they will be invoked in the order they were added.

You can configure your Aspire application to push container images to registries like GitHub Container Registry (GHCR), Docker Hub, or private registries using the AddContainerRegistry method.

Use the AddContainerRegistry method to define a container registry and the WithContainerRegistry method to associate resources with that registry:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Add a container registry
var registry = builder.AddContainerRegistry(
"ghcr", // Registry name
"ghcr.io", // Registry endpoint
"your-github-username/your-repo" // Repository path
);
// Associate resources with the registry
var api = builder.AddProject<Projects.Api>("api")
.PublishAsDockerComposeService()
.WithContainerRegistry(registry);
// After adding all resources, run the app...

For GitHub Container Registry, the registry endpoint is ghcr.io and the repository path typically follows the pattern owner/repository.

Using parameters for registry configuration

Section titled “Using parameters for registry configuration”

For more flexible configuration, especially in CI/CD pipelines, you can use parameters with environment variables:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Define parameters from configuration (reads from environment variables)
var registryEndpoint = builder.AddParameterFromConfiguration("REGISTRY_ENDPOINT");
var registryRepository = builder.AddParameterFromConfiguration("REGISTRY_REPOSITORY");
// Add registry with parameters
var registry = builder.AddContainerRegistry(
"my-registry",
registryEndpoint,
registryRepository
);
var api = builder.AddProject<Projects.Api>("api")
.PublishAsDockerComposeService()
.WithContainerRegistry(registry);

You can then provide parameter values via environment variables:

Terminal window
export REGISTRY_ENDPOINT=ghcr.io
export REGISTRY_REPOSITORY=your-github-username/your-repo

After configuring your container registry, use the aspire do push command to build and push your container images:

Terminal window
aspire do push

This command:

  • Builds container images for all resources configured with a container registry
  • Tags the images with the appropriate registry path
  • Pushes the images to the specified registry

Before running this command, ensure you are authenticated to your container registry. For GitHub Container Registry:

Terminal window
echo $GITHUB_TOKEN | docker login ghcr.io -u your-github-username --password-stdin

Here’s an example GitHub Actions workflow that builds and pushes images to GHCR:

YAML — .github/workflows/build-and-push.yml
name: Build and Push Images
on:
push:
branches: [main]
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Install Aspire CLI
run: |
curl -sSL https://aspire.dev/install.sh | bash
echo "$HOME/.aspire/bin" >> $GITHUB_PATH
- name: Output Aspire CLI version
run: aspire --version
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push images
env:
REGISTRY_ENDPOINT: ghcr.io
REGISTRY_REPOSITORY: ${{ github.repository }}
run: aspire do push

This workflow:

  • Checks out your code
  • Sets up .NET and installs the Aspire CLI
  • Authenticates to GHCR using the built-in GITHUB_TOKEN
  • Builds and pushes container images using aspire do push