Docker integration
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
Hosting integration
Section titled “Hosting integration”The Docker hosting integration is available in the 📦 Aspire.Hosting.Docker NuGet package:
aspire add dockerThe Aspire CLI is interactive, be sure to select the appropriate search result when prompted:
Select an integration to add:
> docker (Aspire.Hosting.Docker)> Other results listed as selectable options...#:package Aspire.Hosting.Docker@*<PackageReference Include="Aspire.Hosting.Docker" Version="*" />Add Docker Compose environment resource
Section titled “Add Docker Compose environment resource”The following example demonstrates how to add a Docker Compose environment to your app model using the AddDockerComposeEnvironment method:
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 configurationbuilder.AddDockerComposeEnvironment("compose") .WithDashboard(dashboard => { dashboard.WithHostPort(8080) .WithForwardedHeaders(enabled: true); });
// Disable dashboardbuilder.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.
Publishing and deployment
Section titled “Publishing and deployment”Aspire provides a progressive deployment workflow for Docker Compose, allowing you to publish, prepare environments, and deploy in separate steps or all at once.
Step 1: Publish the Application
Section titled “Step 1: Publish the Application”To generate Docker Compose files and artifacts without building container images, use the aspire publish command:
aspire publishThis command:
- Generates a
docker-compose.yamlfrom the app host - Generates a
.envfile with expected parameters (unfilled) - Outputs everything to the
aspire-outputdirectory
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:
# For staging environmentaspire do prepare-compose --environment staging
# For production environmentaspire do prepare-compose --environment productionThese commands:
- Generate a
docker-compose.yamlfrom the app host - Generate environment-specific
.envfiles with filled-in values - Generate container images
- Outputs everything to the
aspire-outputdirectory
Step 3: Deploy to Docker Compose
Section titled “Step 3: Deploy to Docker Compose”To perform the complete deployment workflow in one step, use the aspire deploy command:
aspire deployThis command:
- Generates a
docker-compose.yamlfrom the app host - Generates environment-specific
.envfiles with filled-in values - Generates container images
- Outputs everything to the
aspire-outputdirectory - Runs
docker compose upagainst the generated files
Cleaning Up Deployment (Optional)
Section titled “Cleaning Up Deployment (Optional)”To clean up a running Docker Compose deployment, use the aspire do docker-compose-down-{resource-name} command:
aspire do docker-compose-down-composeThis command stops and removes all containers, networks, and volumes created by the Docker Compose deployment.
Environment variables
Section titled “Environment variables”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.
Customize environment file
Section titled “Customize environment file”For advanced scenarios, use ConfigureEnvFile to customize the generated .env file:
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.
Customize container image push options
Section titled “Customize container image push options”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
Set remote image name and tag
Section titled “Set remote image name and tag”Use WithRemoteImageName and WithRemoteImageTag to customize the image reference:
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...Advanced customization with callbacks
Section titled “Advanced customization with callbacks”For more complex scenarios, use WithImagePushOptions to register a callback that can dynamically configure push options:
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:
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.
Push images to container registries
Section titled “Push images to container registries”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.
Configure a container registry
Section titled “Configure a container registry”Use the AddContainerRegistry method to define a container registry and the WithContainerRegistry method to associate resources with that registry:
var builder = DistributedApplication.CreateBuilder(args);
// Add a container registryvar registry = builder.AddContainerRegistry( "ghcr", // Registry name "ghcr.io", // Registry endpoint "your-github-username/your-repo" // Repository path);
// Associate resources with the registryvar 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:
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 parametersvar 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:
export REGISTRY_ENDPOINT=ghcr.ioexport REGISTRY_REPOSITORY=your-github-username/your-repo$env:REGISTRY_ENDPOINT = "ghcr.io"$env:REGISTRY_REPOSITORY = "your-github-username/your-repo"Push images with the Aspire CLI
Section titled “Push images with the Aspire CLI”After configuring your container registry, use the aspire do push command to build and push your container images:
aspire do pushThis 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:
echo $GITHUB_TOKEN | docker login ghcr.io -u your-github-username --password-stdinGitHub Actions workflow example
Section titled “GitHub Actions workflow example”Here’s an example GitHub Actions workflow that builds and pushes images to GHCR:
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 pushThis 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