コンテンツにスキップ
Docs Try Aspire
Docs Try

アプリモデルに Dockerfile を追加する

Aspire では、AddDockerfile または WithDockerfile 拡張メソッドを使用して、AppHost の起動時にビルドする Dockerfile を指定できます。

この 2 つのメソッドは異なる目的に使用します:

  • AddDockerfile: 既存の Dockerfile から新しいコンテナーリソースを作成します。カスタムのコンテナー化サービスをアプリモデルに追加したい場合に使用します。
  • WithDockerfile: 既存のコンテナーリソース (データベースやキャッシュなど) をカスタマイズして別の Dockerfile を使用するようにします。Aspire コンポーネントのデフォルトコンテナーイメージを変更したい場合に使用します。

いずれのメソッドも、指定したコンテキストパスに既存の Dockerfile があることを前提としています。どちらのメソッドも Dockerfile を新規作成しません。AppHost コードから Dockerfile を生成するには、代わりに Dockerfile ビルダー API を使用してください。

AddDockerfile と WithDockerfile の使い分け

Section titled “AddDockerfile と WithDockerfile の使い分け”

シナリオに応じて適切なメソッドを選択してください:

AddDockerfile を使用する場合:

  • カスタムのコンテナー化サービスをアプリモデルに追加したい場合。
  • カスタムアプリケーションまたはサービス用の既存の Dockerfile がある場合。
  • Aspire コンポーネントが提供していない新しいコンテナーリソースを作成する必要がある場合。

WithDockerfile を使用する場合:

  • 既存の Aspire コンポーネント (PostgreSQL、Redis など) をカスタマイズしたい場合。
  • デフォルトのコンテナーイメージをカスタムのものに置き換える必要がある場合。
  • 厳密に型指定されたリソースビルダーとその拡張メソッドを引き続き使用したい場合。
  • デフォルトのコンテナーイメージでは対応できない要件がある場合。

アプリモデルに Dockerfile を追加する

Section titled “アプリモデルに Dockerfile を追加する”

次の例では、AddDockerfile 拡張メソッドを使用して、コンテナービルドのコンテキストパスを参照することでコンテナーを指定しています。

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.AddDockerfile(
"mycontainer", "relative/context/path");

コンテキストパスの引数がルートパスでない場合、コンテキストパスは AppHost プロジェクトディレクトリからの相対パスとして解釈されます。

デフォルトでは使用される Dockerfile の名前は Dockerfile であり、コンテキストパスディレクトリ内に存在することが期待されます。Dockerfile の名前は絶対パスまたはコンテキストパスへの相対パスとして明示的に指定することもできます。

これは、ローカルで実行する場合や AppHost がデプロイする際に使用する特定の Dockerfile を変更したい場合に便利です。

AppHost.cs
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");

既存のコンテナーリソースをカスタマイズする

Section titled “既存のコンテナーリソースをカスタマイズする”

AddDockerfile を使用する場合、戻り値は IResourceBuilder<ContainerResource> です。Aspire には ContainerResource から派生した多くのカスタムリソース型が含まれています。

WithDockerfile 拡張メソッドを使用すると、既存の Aspire コンポーネント (PostgreSQL、Redis、SQL Server など) のデフォルトコンテナーイメージを、独自の Dockerfile からビルドしたカスタムイメージに置き換えることができます。これにより、基盤となるコンテナーをカスタマイズしながら、厳密に型指定されたリソース型とその固有の拡張メソッドを引き続き使用できます。

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// デフォルトの PostgreSQL コンテナーイメージをカスタムイメージに置き換えます
// Dockerfile からビルドしたものを使用し、PostgreSQL 固有の機能は維持されます
var pgsql = builder.AddPostgres("pgsql")
.WithDockerfile("path/to/context")
.WithPgAdmin(); // PostgreSQL リソースであることに変わりないため、引き続き動作します

Dockerfile をプログラムで生成する

Section titled “Dockerfile をプログラムで生成する”

AddDockerfileBuilder または WithDockerfileBuilder は、AppHost コードから Dockerfile を生成する必要がある場合に使用します。これらの API は、Dockerfile が AppHost の設定に依存する場合、Dockerfile フラグメントを組み合わせたい場合、またはマルチステージイメージのビルドロジックをリソース定義の近くに保ちたい場合に便利です。

AddDockerfileBuilder は、新しいコンテナーリソースを作成し、生成された Dockerfile を 1 ステップで設定します:

AppHost.cs
using Aspire.Hosting.ApplicationModel.Docker;
var builder = DistributedApplication.CreateBuilder(args);
#pragma warning disable ASPIREDOCKERFILEBUILDER001
builder.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();

WithDockerfileBuilder は、既存のコンテナーリソースに生成された Dockerfile を適用します。リソースの作成時に指定されたイメージ名は、パブリッシュ時に生成された Dockerfile のビルドに置き換えられます:

AppHost.cs
using Aspire.Hosting.ApplicationModel.Docker;
var builder = DistributedApplication.CreateBuilder(args);
#pragma warning disable ASPIREDOCKERFILEBUILDER001
builder.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();

WithBuildArg メソッドを使用して、コンテナーイメージのビルドに引数を渡すことができます。

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var container = builder.AddDockerfile("mygoapp", "relative/context/path")
.WithBuildArg("GO_VERSION", "1.22");

WithBuildArg メソッドの値パラメーターには、リテラル値 (booleanstringint) またはパラメーターリソースのリソースビルダーを指定できます (パラメーターリソース を参照)。次のコードでは、GO_VERSION をデプロイ時に指定できるパラメーター値に置き換えます。

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var goVersion = builder.AddParameter("goversion");
var container = builder.AddDockerfile("mygoapp", "relative/context/path")
.WithBuildArg("GO_VERSION", goVersion);

ビルド引数は DockerfilesARG コマンド に対応します。前述の例を拡張したマルチステージ Dockerfile では、使用するコンテナーイメージのバージョンをパラメーターとして指定しています。

Dockerfile
# Stage 1: Go プログラムをビルドする
ARG GO_VERSION=1.22
FROM golang:${GO_VERSION} AS builder
WORKDIR /build
COPY . .
RUN go build mygoapp.go
# Stage 2: Go プログラムを実行する
FROM mcr.microsoft.com/cbl-mariner/base/core:2.0
WORKDIR /app
COPY --from=builder /build/mygoapp .
CMD ["./mygoapp"]

ビルド引数に加え、WithBuildSecret を使用してビルドシークレットを指定できます。シークレットは、RUN コマンドの --mount=type=secret 構文を使用して Dockerfile 内の個別のコマンドに選択的に公開されます。

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var accessToken = builder.AddParameter("accesstoken", secret: true);
var container = builder.AddDockerfile("myapp", "relative/context/path")
.WithBuildSecret("ACCESS_TOKEN", accessToken);

たとえば、DockerfileRUN コマンドで指定したシークレットを特定のコマンドに公開する場合を考えてみましょう:

Dockerfile
# helloworld コマンドは /run/secrets/ACCESS_TOKEN からシークレットを読み取ることができます
RUN --mount=type=secret,id=ACCESS_TOKEN helloworld