Add Dockerfiles to your app model
Ce contenu n’est pas encore disponible dans votre langue.
With Aspire it’s possible to specify a Dockerfile to build when the AppHost is started using either the AddDockerfile or WithDockerfile extension methods.
These two methods serve different purposes:
AddDockerfile: Creates a new container resource from an existing Dockerfile. Use this when you want to add a custom containerized service to your app model.WithDockerfile: Customizes an existing container resource (like a database or cache) to use a different Dockerfile. Use this when you want to modify the default container image for an Aspire component.
Both methods expect an existing Dockerfile in the specified context path—neither method creates a Dockerfile for you. To generate a Dockerfile from AppHost code instead, use the Dockerfile builder APIs or the Dockerfile factory APIs.
When to use AddDockerfile vs WithDockerfile
Section titled “When to use AddDockerfile vs WithDockerfile”Choose the appropriate method based on your scenario:
Use AddDockerfile when:
- You want to add a custom containerized service to your app model.
- You have an existing Dockerfile for a custom application or service.
- You need to create a new container resource that isn’t provided by Aspire components.
Use WithDockerfile when:
- You want to customize an existing Aspire component (like PostgreSQL, Redis, etc.).
- You need to replace the default container image with a custom one.
- You want to maintain the strongly typed resource builder and its extension methods.
- You have specific requirements that the default container image doesn’t meet.
Add a Dockerfile to the app model
Section titled “Add a Dockerfile to the app model”In the following example the AddDockerfile extension method is used to specify a container by referencing the context path for the container build.
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.AddDockerfile( "mycontainer", "relative/context/path");import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const container: ContainerResource
container = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, options?: { dockerfilePath?: string; stage?: string;}): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile( "mycontainer", "relative/context/path");Unless the context path argument is a rooted path the context path is interpreted as being relative to the AppHost project directory.
By default the name of the Dockerfile which is used is Dockerfile and is expected to be within the context path directory. It’s possible to explicitly specify the Dockerfile name either as an absolute path or a relative path to the context path.
This is useful if you wish to modify the specific Dockerfile being used when running locally or when the AppHost is deploying.
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.ExecutionContext.IsRunMode ? builder.AddDockerfile( "mycontainer", "relative/context/path", "Dockerfile.debug") : builder.AddDockerfile( "mycontainer", "relative/context/path", "Dockerfile.release");import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const container: ContainerResource
container = (await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.executionContext: PropertyAccessor<DistributedApplicationExecutionContext>
Execution context for this invocation of the AppHost.
executionContext.DistributedApplicationExecutionContext.isRunMode: () => Promise<boolean>
Returns true if the current operation is running.
isRunMode()) ? await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, dockerfilePath?: string, stage?: string): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile( "mycontainer", "relative/context/path", "Dockerfile.debug") : await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, dockerfilePath?: string, stage?: string): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile( "mycontainer", "relative/context/path", "Dockerfile.release");Customize existing container resources
Section titled “Customize existing container resources”When using AddDockerfile the return value is an IResourceBuilder<ContainerResource>. Aspire includes many custom resource types that are derived from ContainerResource.
Using the WithDockerfile extension method it’s possible to take an existing Aspire component (like PostgreSQL, Redis, or SQL Server) and replace its default container image with a custom one built from your own Dockerfile. This allows you to continue using the strongly typed resource types and their specific extension methods while customizing the underlying container.
var builder = DistributedApplication.CreateBuilder(args);
// This replaces the default PostgreSQL container image with a custom one// built from your Dockerfile, while keeping PostgreSQL-specific functionalityvar pgsql = builder.AddPostgres("pgsql") .WithDockerfile("path/to/context") .WithPgAdmin(); // Still works because it's still a PostgreSQL resourceimport { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const pgsql: PostgresServerResource
pgsql = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addPostgres(name: string, options?: { userName?: string | ParameterResource; password?: string | ParameterResource; port?: number;}): PostgresServerResource (+1 overload)
Adds a PostgreSQL resource to the application model. A container is used for local development.
addPostgres("pgsql");
// This replaces the default PostgreSQL container image with a custom one// built from your Dockerfile, while keeping PostgreSQL-specific functionality.await const pgsql: PostgresServerResource
pgsql.ContainerResource.withDockerfile(contextPath: string, options?: { dockerfilePath?: string; stage?: string;} | undefined): PostgresServerResource (+1 overload)
Causes Aspire to build the specified container image from a Dockerfile.
withDockerfile("path/to/context");await const pgsql: PostgresServerResource
pgsql.PostgresServerResource.withPgAdmin(options?: { configureContainer?: ((obj: PgAdminContainerResource) => Promise<void>) | undefined; containerName?: string;} | undefined): PostgresServerResource (+1 overload)
Adds a pgAdmin 4 administration and development platform for PostgreSQL to the application model.
withPgAdmin(); // Still works because it's still a PostgreSQL resource.Generate a Dockerfile programmatically
Section titled “Generate a Dockerfile programmatically”Use AddDockerfileBuilder or WithDockerfileBuilder when you need Aspire to generate a Dockerfile from AppHost code. These APIs are useful when the Dockerfile depends on AppHost configuration, when you want to compose Dockerfile fragments, or when you want to keep multi-stage image build logic near the resource definition.
AddDockerfileBuilder creates a new container resource and configures the generated Dockerfile in one step:
using Aspire.Hosting.ApplicationModel.Docker;
var builder = DistributedApplication.CreateBuilder(args);
#pragma warning disable ASPIREDOCKERFILEBUILDER001builder.AddDockerfileBuilder("frontend", "../frontend", context =>{ var build = context.Builder.From("node:22-alpine", "build"); build.WorkDir("/app") .Copy("package*.json", "./") .Run("npm ci") .Copy(".", ".") .Run("npm run build");
var runtime = context.Builder.From("nginx:alpine", "runtime"); runtime.CopyFrom("build", "/app/dist", "/usr/share/nginx/html") .Expose(80);
return Task.CompletedTask;}, stage: "runtime");#pragma warning restore ASPIREDOCKERFILEBUILDER001
builder.Build().Run();import { createBuilder } from './.aspire/modules/aspire.mjs';import type { DockerfileBuilderCallbackContext } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const configureDockerfile = async (context: DockerfileBuilderCallbackContext) => { const dockerfile = await context.builder();
await dockerfile .from("node:22-alpine", { stageName: "build" }) .workDir("/app") .copy("package*.json", "./") .run("npm ci") .copy(".", ".") .run("npm run build");
await dockerfile .from("nginx:alpine", { stageName: "runtime" }) .copyFrom("build", "/app/dist", "/usr/share/nginx/html") .expose(80);};
await builder.addDockerfileBuilder("frontend", "../frontend", configureDockerfile, { stage: "runtime",});
await builder.build().run();WithDockerfileBuilder applies a generated Dockerfile to an existing container resource. The image name provided when the resource is created is replaced by the generated Dockerfile build during publish:
using Aspire.Hosting.ApplicationModel.Docker;
var builder = DistributedApplication.CreateBuilder(args);
#pragma warning disable ASPIREDOCKERFILEBUILDER001builder.AddContainer("frontend", "nginx:alpine") .WithDockerfileBuilder("../frontend", context => { var stage = context.Builder.From("nginx:alpine", "runtime"); stage.Copy(".", "/usr/share/nginx/html") .Expose(80);
return Task.CompletedTask; }, stage: "runtime");#pragma warning restore ASPIREDOCKERFILEBUILDER001
builder.Build().Run();import { createBuilder } from './.aspire/modules/aspire.mjs';import type { DockerfileBuilderCallbackContext } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const configureDockerfile = async (context: DockerfileBuilderCallbackContext) => { const dockerfile = await context.builder(); await dockerfile .from("nginx:alpine", { stageName: "runtime" }) .copy(".", "/usr/share/nginx/html") .expose(80);};
await builder .addContainer("frontend", "nginx:alpine") .withDockerfileBuilder("../frontend", configureDockerfile, { stage: "runtime", });
await builder.build().run();Generate a Dockerfile with a factory function
Section titled “Generate a Dockerfile with a factory function”Use AddDockerfileFactory or WithDockerfileFactory when you need to generate a Dockerfile as a string from AppHost code. Unlike the Dockerfile builder APIs that use a fluent API to compose Dockerfile instructions, the factory APIs let you return Dockerfile content directly as a string — useful when you already have string-based Dockerfile generation logic or want to construct content conditionally.
The factory callback receives a DockerfileFactoryContext parameter that provides access to the resource and DI services when needed.
AddDockerfileFactory creates a new container resource and configures the generated Dockerfile in one step:
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.AddDockerfileFactory("myapp", "../myapp", async context =>{ // Return Dockerfile content as a string. return """ FROM node:22-alpine WORKDIR /app COPY . . RUN npm ci EXPOSE 3000 CMD ["node", "server.js"] """;});
builder.Build().Run();import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const container = await builder.addDockerfileFactory("myapp", "../myapp", async () => `FROM node:22-alpineWORKDIR /appCOPY . .RUN npm ciEXPOSE 3000CMD ["node", "server.js"]`);
await builder.build().run();WithDockerfileFactory applies a factory-generated Dockerfile to an existing container resource:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("myapp", "placeholder") .WithDockerfileFactory("../myapp", async context => { return """ FROM nginx:alpine COPY dist/ /usr/share/nginx/html EXPOSE 80 """; });
builder.Build().Run();import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
await builder.addContainer("myapp", { image: "placeholder", tag: "latest" }) .withDockerfileFactory("../myapp", async () => `FROM nginx:alpineCOPY dist/ /usr/share/nginx/htmlEXPOSE 80`);
await builder.build().run();Pass build arguments
Section titled “Pass build arguments”The WithBuildArg method can be used to pass arguments into the container image build.
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.AddDockerfile("mygoapp", "relative/context/path") .WithBuildArg("GO_VERSION", "1.22");import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const container: ContainerResource
container = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, options?: { dockerfilePath?: string; stage?: string;}): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile("mygoapp", "relative/context/path");await const container: ContainerResource
container.ContainerResource.withBuildArg(name: string, value: string | ParameterResource): ContainerResource
Adds a build argument when the container is built from a Dockerfile.
withBuildArg("GO_VERSION", "1.22");The value parameter on the WithBuildArg method can be a literal value (boolean, string, int) or it can be a resource builder for a parameter resource. The following code replaces the GO_VERSION with a parameter value that can be specified at deployment time.
var builder = DistributedApplication.CreateBuilder(args);
var goVersion = builder.AddParameter("goversion");
var container = builder.AddDockerfile("mygoapp", "relative/context/path") .WithBuildArg("GO_VERSION", goVersion);import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const goVersion: ParameterResource
goVersion = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addParameter(name: string, options?: { value?: string; publishValueAsDefault?: boolean; secret?: boolean;}): ParameterResource (+1 overload)
Adds a parameter resource
addParameter("goversion");
const const container: ContainerResource
container = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, options?: { dockerfilePath?: string; stage?: string;}): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile("mygoapp", "relative/context/path");await const container: ContainerResource
container.ContainerResource.withBuildArg(name: string, value: string | ParameterResource): ContainerResource
Adds a build argument when the container is built from a Dockerfile.
withBuildArg("GO_VERSION", const goVersion: ParameterResource
goVersion);Build arguments correspond to the ARG command in Dockerfiles. Expanding the preceding example, this is a multi-stage Dockerfile which specifies specific container image version to use as a parameter.
# Stage 1: Build the Go programARG GO_VERSION=1.22FROM golang:${GO_VERSION} AS builderWORKDIR /buildCOPY . .RUN go build mygoapp.go
# Stage 2: Run the Go programFROM mcr.microsoft.com/cbl-mariner/base/core:2.0WORKDIR /appCOPY --from=builder /build/mygoapp .CMD ["./mygoapp"]Pass build secrets
Section titled “Pass build secrets”In addition to build arguments it’s possible to specify build secrets using WithBuildSecret which are made selectively available to individual commands in the Dockerfile using the --mount=type=secret syntax on RUN commands.
var builder = DistributedApplication.CreateBuilder(args);
var accessToken = builder.AddParameter("accesstoken", secret: true);
var container = builder.AddDockerfile("myapp", "relative/context/path") .WithBuildSecret("ACCESS_TOKEN", accessToken);import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const accessToken: ParameterResource
accessToken = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addParameter(name: string, options?: { value?: string; publishValueAsDefault?: boolean; secret?: boolean;}): ParameterResource (+1 overload)
Adds a parameter resource
addParameter("accesstoken", { secret?: boolean | undefined
secret: true });
const const container: ContainerResource
container = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addDockerfile(name: string, contextPath: string, options?: { dockerfilePath?: string; stage?: string;}): ContainerResource (+1 overload)
Adds a Dockerfile to the application model that can be treated like a container resource.
addDockerfile("myapp", "relative/context/path");await const container: ContainerResource
container.ContainerResource.withBuildSecret(name: string, value: string | ParameterResource): ContainerResource
Adds a secret build argument when the container is built from a Dockerfile.
withBuildSecret("ACCESS_TOKEN", const accessToken: ParameterResource
accessToken);For example, consider the RUN command in a Dockerfile which exposes the specified secret to the specific command:
# The helloworld command can read the secret from /run/secrets/ACCESS_TOKENRUN --mount=type=secret,id=ACCESS_TOKEN helloworld