6.8 KiB
Docker Compose deployment
Use this reference when the user asks for Docker Compose deployment, local container deployment artifacts, or a non-cloud deployment package.
Docs to load
Always start with current docs:
aspire docs search "Docker Compose deployment"
aspire docs search "Docker hosting integration"
aspire docs search "Docker Compose environment variables"
aspire docs get "deploy-to-docker-compose"
aspire docs get "docker-integration"
aspire docs get "<slug>"
Use API docs before editing. Search in the AppHost language you detected:
aspire docs api search "Docker Compose environment" --language csharp
aspire docs api search "Docker Compose environment" --language typescript
aspire docs api search "Docker Compose service customization" --language csharp
aspire docs api search "Docker Compose service customization" --language typescript
Target setup
Expected package and AppHost environment:
aspire add docker
Add a Docker Compose environment resource using the C# or TypeScript API shape returned by Aspire docs. When a Docker Compose environment exists, compatible resources are automatically included in generated Compose output. Use the per-resource Docker Compose customization API only for customization.
Code changes to make
Make these changes in the AppHost, not in the generated Compose output:
-
Run
aspire add dockerif the AppHost does not already reference the Docker hosting integration. -
Add a Docker Compose environment resource.
C# AppHost shape:
var compose = builder.AddDockerComposeEnvironment("docker-compose");TypeScript AppHost shape:
const compose = await builder.addDockerComposeEnvironment("docker-compose"); -
Do not add explicit compute-environment assignment for the common single-environment case. Only if the AppHost has multiple compute environments, disambiguate each Docker Compose workload; in C#, add
.WithComputeEnvironment(compose)to each compute resource that should land in Compose. -
For TypeScript AppHosts, verify the current language-specific docs before assuming an equivalent assignment API.
-
Keep normal app model relationships such as
WithReference, endpoints, parameters, and connection strings in the AppHost. They flow into Compose environment variables and service dependencies. -
Use customization APIs only for real Compose customization:
- C#:
compose.ConfigureComposeFile(...),compose.ConfigureEnvFile(...), andresource.PublishAsDockerComposeService(...). - TypeScript:
compose.configureComposeFile(...),compose.configureEnvFile(...), andresource.publishAsDockerComposeService(...).
- C#:
Do not hand-edit docker-compose.yaml as the durable fix unless the user explicitly wants to eject generated artifacts.
Preflight
Check:
- Docker or Podman is installed and running.
- Docker must be at least 28.0.0, and Podman must be at least 5.0.0 for current Aspire CLI environment checks.
- The AppHost has a Docker Compose environment resource.
- The repo does not rely on local bind mounts that will be invalid on the target Docker host.
- Parameters and secrets are represented as placeholders in
.envafteraspire publishand resolved in.env.<environment>after prepare/deploy. - Any fixed ports are intentional and do not conflict on the deployment host.
Use ASPIRE_CONTAINER_RUNTIME=docker or ASPIRE_CONTAINER_RUNTIME=podman only when the user needs to force a runtime.
Preview and publish
Generate artifacts without starting containers:
aspire publish
Expected output includes:
aspire-output/docker-compose.yamlaspire-output/.env- resource Dockerfiles when needed
For environment-specific output and image build without running the whole deploy, use the target's prepare step if docs/list-steps show it:
aspire deploy --list-steps
aspire do prepare-docker-compose --environment staging
The exact step name depends on the Docker Compose environment resource name. Use the step shown by aspire deploy --list-steps: for an environment resource named docker-compose, the prepare step is prepare-docker-compose; for one named compose, it is prepare-compose.
Deploy and destroy
Deploy:
aspire deploy
Aspire generates Compose output, builds images, writes environment-specific .env files, and runs Compose.
Run the Docker Compose target's destroy pipeline only when requested:
aspire destroy
For Docker Compose, aspire destroy delegates to the Compose deployment target for the selected AppHost/environment. Use Docker or Compose commands after destroy only to verify cleanup or investigate leftover containers, networks, volumes, or generated files.
Common decisions
Publish-only vs deploy
Use aspire publish when the user wants files to review or hand to another deployment system. Use aspire deploy when they want Aspire to start the Compose deployment.
aspire publish writes docker-compose.yaml and .env with blank placeholders for captured values. Prepare/deploy writes .env.<environment> with resolved values. Do not expect aspire deploy to consume a previously published directory.
Customizing generated Compose
Use docs-backed APIs:
- The Compose file customization API for global Compose model changes.
- The environment file customization API for generated
.envchanges. - The per-resource Docker Compose service customization API for service-level changes.
Do not hand-edit generated docker-compose.yaml as the source of truth unless the user explicitly wants to eject the artifact.
Environment files and bind mounts
Generated .env values are intentionally separated from environment-specific .env.<environment> values:
.envis a publish-time placeholder file and preserves existing user values when possible..env.<environment>is written by prepare/deploy with resolved parameter, image, and bind-mount values.- Project images are represented through image placeholders such as
<RESOURCE>_IMAGEuntil prepare/deploy resolves them. - Bind mount source paths are replaced by
<RESOURCE>_BINDMOUNT_<index>placeholders because local paths often do not exist on another Docker host. - Docker socket mounts are left as the platform socket path instead of being placeholderized.
Treat .env.<environment> as potentially sensitive.
Compose project name
Aspire uses a generated Compose project name based on the environment resource name and, when available, the AppHost path hash. This prevents common collisions between different AppHosts using the same environment name.
Service host names
When a service needs another service's Compose host name, use the Docker Compose environment's host address expression API from docs. Do not hardcode generated service names unless the docs or artifact prove them.