コンテンツにスキップ

最初のアプリをデプロイする

最初にプログラミング言語を選択しましょう

このチュートリアルでは、 最初のアプリを作成する のクイックスタートで作成したアプリをデプロイします。この作業は、いくつかの重要なステップに分けて進めることができます。:

  1. デプロイパッケージを追加する — 対象環境向けのホスティングパッケージを追加します。
  2. AppHost を更新する — 環境 API を構成します。
  3. アプリをデプロイする — Aspire CLI を使ってアプリをデプロイします。
  4. デプロイを検証する — アプリが期待どおりに動作していることを確認します。
  5. リソースをクリーンアップする — コストが発生しないよう、デプロイ済みリソースを削除します。

次の図は、これからデプロイするサンプルアプリのアーキテクチャを示しています:

architecture-beta
    group api-docker(logos:docker-icon)[API container]
    group f-docker(logos:docker-icon)[Front end container]

    service api(logos:dotnet)[API service] in api-docker
    service http(iconoir:server-connection)[https]
    service frontend(aspire:blazor)[Blazor front end] in f-docker

    frontend:L --> R:http
    http:L --> R:api

ASP.NET Core Blazor & Minimal API のスターターテンプレートは、2 つのリソースで構成されており、それぞれが個別のコンテナーとしてデプロイされます。

architecture-beta
  group docker(logos:docker-icon)[Python and static site server container]  

  service api(logos:fastapi)[API service] in docker
  service http(iconoir:server-connection)[https] in docker
  service frontend(logos:react)[React front end] in docker

  frontend:L --> R:http
  http:L --> R:api

React(Vite)と FastAPI のスターターテンプレートは、2 つのリソースで構成されていますが、1 つのコンテナーとしてデプロイされます。FastAPI サーバーが、API と React によって生成された静的フロントエンドファイルの双方をホストします。

Aspire アプリをデプロイする場所に応じて、次の前提条件がインストールされ、設定されていることを確認してください:

Docker ロゴ

デプロイ パッケージを追加する

Section titled “デプロイ パッケージを追加する”

前のクイックスタートで作成した Aspire ソリューションの ルートディレクトリ で、次のコマンドをターミナルで実行し、対象環境に応じたホスティング用デプロイパッケージを追加してください:

Docker Compose は、複数のコンテナーで構成される Docker アプリケーションを定義し、実行するためのツールです。YAML ファイルを使用して、アプリケーションの サービス、ネットワーク、ボリューム を構成できるため、複雑なアプリケーションをローカルやさまざまな環境で管理・デプロイしやすくなります。

Aspire CLI — Docker Compose を追加
aspire add docker

Aspire CLI は対話形式のため、 📦 Aspire.Hosting.Docker の追加したいバージョンに対応する検索結果を正しく選択してください。

追加の選択肢が表示された場合は、 Up Arrow Up Arrow Up Arrow および Down Arrow Down Arrow Down Arrow キーでオプションを移動し、 Return Enter Enter を押して選択を確定してください。

aspire add コマンドの詳細については、 リファレンス ドキュメントをご覧ください。

AppHost では、ターゲットに合わせてデプロイ環境を構成するために、適切な環境 API メソッド呼び出しをチェーンしてください。

C# — AppHost.cs project-based orchestrator
var builder = DistributedApplication.CreateBuilder(args);
// Add the following line to configure the Docker Compose environment
builder.AddDockerComposeEnvironment("env");
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithHttpHealthCheck("/health");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithHttpHealthCheck("/health")
.WithReference(apiService)
.WaitFor(apiService);
builder.Build().Run();
C# — apphost.cs file-based orchestrator
#:sdk Aspire.AppHost.Sdk@13.0.0
#:package Aspire.Hosting.JavaScript@13.0.0
#:package Aspire.Hosting.Python@13.0.0
#:package Aspire.Hosting.Docker@13.0.0
var builder = DistributedApplication.CreateBuilder(args);
// Add the following line to configure the Docker Compose environment
builder.AddDockerComposeEnvironment("env");
var app = builder.AddUvicornApp("app", "./app", "main:app")
.WithUv()
.WithExternalHttpEndpoints()
.WithHttpHealthCheck("/health");
var frontend = builder.AddViteApp("frontend", "./frontend")
.WithReference(app)
.WaitFor(app);
app.PublishWithContainerFiles(frontend, "./static");
builder.Build().Run();
  • AddDockerComposeEnvironment — デプロイ用の Docker Compose 環境を構成します。この呼び出しにより、AppHost 内のリソースをデプロイ時にコンテナ化するためのサポートが暗黙的に追加されます。
  • WithExternalHttpEndpoints — デプロイ時に、リソースの HTTP エンドポイントを外部へ公開します。

デプロイ パッケージを追加し、AppHost の更新も完了したら、いよいよ Aspire アプリをデプロイできます。

Docker Compose へのデプロイでは、コンテナー イメージをビルドし、Docker Compose を使用してローカルでサービスを起動します。

Aspire CLI — Deploy your app
aspire deploy

次の出力例を確認してください:

ASP.NET Core/Blazor アプリを Docker Compose にデプロイした際の出力例
Aspire CLI - ASP.NET Core/Blazor アプリを Docker Compose にデプロイ
14:28:15 (pipeline execution) → Starting pipeline execution...
14:28:15 (build-prereq) → Starting build-prereq...
14:28:15 (publish-env) → Starting publish-env...
14:28:15 (deploy-prereq) → Starting deploy-prereq...
14:28:15 (build-prereq) ✓ build-prereq completed successfully
14:28:15 (deploy-prereq) i [INF] Initializing deployment for environment 'Production'
14:28:15 (publish-env) i [INF] Generating Compose output
14:28:15 (deploy-prereq) i [INF] Setting default deploy tag 'aspire-deploy-20251107202815' for compute resource(s).
14:28:15 (deploy-prereq) ✓ deploy-prereq completed successfully
14:28:15 (build-webfrontend) → Starting build-webfrontend...
14:28:15 (build-apiservice) → Starting build-apiservice...
14:28:15 (publish-env) → Writing the Docker Compose file to the output path.
14:28:15 (build-webfrontend) i [INF] Building container image for resource webfrontend
14:28:15 (build-apiservice) i [INF] Building container image for resource apiservice
14:28:15 (build-webfrontend) i [INF] Building image: webfrontend
14:28:15 (publish-env) ✓ Docker Compose file written successfully to .\AspireApp\AspireApp.AppHost\aspire-output\docker-compose.yaml. (0.0s)
14:28:15 (publish-env) ✓ publish-env completed successfully
14:28:15 (publish) → Starting publish...
14:28:15 (publish) ✓ publish completed successfully
14:28:28 (build-webfrontend) i [INF] Building image for webfrontend completed
14:28:28 (build-apiservice) i [INF] Building image: apiservice
14:28:28 (build-webfrontend) ✓ build-webfrontend completed successfully
14:28:32 (build-apiservice) i [INF] Building image for apiservice completed
14:28:32 (build-apiservice) ✓ build-apiservice completed successfully
14:28:32 (build) → Starting build...
14:28:32 (build) ✓ build completed successfully
14:28:32 (prepare-env) → Starting prepare-env...
14:28:32 (prepare-env) ✓ prepare-env completed successfully
14:28:32 (docker-compose-up-env) → Starting docker-compose-up-env...
14:28:32 (docker-compose-up-env) → Running docker compose up for env
14:28:35 (docker-compose-up-env) ✓ Service env is now running with Docker Compose locally (2.3s)
14:28:35 (docker-compose-up-env) ✓ docker-compose-up-env completed successfully
14:28:35 (print-env-dashboard-summary) → Starting print-env-dashboard-summary...
14:28:35 (print-webfrontend-summary) → Starting print-webfrontend-summary...
14:28:35 (print-env-dashboard-summary) i [INF] Successfully deployed env-dashboard to http://localhost:54633.
14:28:35 (print-webfrontend-summary) i [INF] Successfully deployed webfrontend to http://localhost:54463.
14:28:35 (print-env-dashboard-summary) ✓ print-env-dashboard-summary completed successfully
14:28:35 (print-webfrontend-summary) ✓ print-webfrontend-summary completed successfully
14:28:35 (deploy) → Starting deploy...
14:28:35 (deploy) ✓ deploy completed successfully
14:28:35 (pipeline execution) ✓ Completed successfully
------------------------------------------------------------
13/13 steps succeeded Total time: 20.0s
Steps Summary:
19.9 s pipeline execution
17.6 s build-apiservice
12.9 s build-webfrontend
2.3 s docker-compose-up-env
0.0 s publish-env
0.0 s deploy-prereq
0.0 s build-prereq
0.0 s build
0.0 s prepare-env
0.0 s print-env-dashboard-summary
0.0 s print-webfrontend-summary
0.0 s deploy
0.0 s publish
PIPELINE SUCCEEDED
------------------------------------------------------------
Python/React アプリを Docker Compose にデプロイした際の出力例
Aspire CLI - Python/React アプリを Docker Compose にデプロイ
13:23:29 (pipeline execution) → Starting pipeline execution...
13:23:29 (publish-env) → Starting publish-env...
13:23:29 (build-prereq) → Starting build-prereq...
13:23:29 (deploy-prereq) → Starting deploy-prereq...
13:23:29 (build-prereq) ✓ build-prereq completed successfully
13:23:29 (deploy-prereq) i [INF] Initializing deployment for environment 'Production'
13:23:29 (publish-env) i [INF] Generating Compose output
13:23:29 (deploy-prereq) i [INF] Setting default deploy tag 'aspire-deploy-20251107192329' for compute resource(s).
13:23:29 (deploy-prereq) ✓ deploy-prereq completed successfully
13:23:29 (build-frontend) → Starting build-frontend...
13:23:29 (build-frontend) i [INF] Building container image for resource frontend
13:23:29 (build-frontend) i [INF] Building image: frontend
13:23:29 (publish-env) → Writing the Docker Compose file to the output path.
13:23:29 (publish-env) ✓ Docker Compose file written successfully to ./aspire-app/aspire-output/docker-compose.yaml. (0.0s)
13:23:29 (publish-env) ✓ publish-env completed successfully
13:23:29 (publish) → Starting publish...
13:23:29 (publish) ✓ publish completed successfully
13:23:51 (build-frontend) i [INF] docker buildx for frontend:5ee04da8ac438e73afdb5ab3a7b551d3be1a5feb succeeded.
13:23:51 (build-frontend) i [INF] Building image for frontend completed
13:23:51 (build-frontend) ✓ build-frontend completed successfully
13:23:51 (build-app) → Starting build-app...
13:23:51 (build-app) i [INF] Building container image for resource app
13:23:51 (build-app) i [INF] Building image: app
13:24:07 (build-app) i [INF] docker buildx for app:5d592d0c1d2f417b0c14c4c4a9efb4f0760be8e4 succeeded.
13:24:07 (build-app) i [INF] Building image for app completed
13:24:07 (build-app) ✓ build-app completed successfully
13:24:07 (build) → Starting build...
13:24:07 (build) ✓ build completed successfully
13:24:07 (prepare-env) → Starting prepare-env...
13:24:07 (prepare-env) ✓ prepare-env completed successfully
13:24:07 (docker-compose-up-env) → Starting docker-compose-up-env...
13:24:07 (docker-compose-up-env) → Running docker compose up for env
13:24:13 (docker-compose-up-env) ✓ Service env is now running with Docker Compose locally (5.6s)
13:24:13 (docker-compose-up-env) ✓ docker-compose-up-env completed successfully
13:24:13 (print-env-dashboard-summary) → Starting print-env-dashboard-summary...
13:24:13 (print-app-summary) → Starting print-app-summary...
13:24:13 (print-env-dashboard-summary) i [INF] Successfully deployed env-dashboard to http://localhost:54633.
13:24:13 (print-app-summary) i [INF] Successfully deployed app to http://localhost:54463.
13:24:13 (print-env-dashboard-summary) ✓ print-env-dashboard-summary completed successfully
13:24:13 (print-app-summary) ✓ print-app-summary completed successfully
13:24:13 (deploy) → Starting deploy...
13:24:13 (deploy) ✓ deploy completed successfully
13:24:13 (pipeline execution) ✓ Completed successfully
------------------------------------------------------------
13/13 steps succeeded Total time: 44.1s
Steps Summary:
44.0 s pipeline execution
22.2 s build-frontend
16.3 s build-app
5.6 s docker-compose-up-env
0.0 s publish-env
0.0 s deploy-prereq
0.0 s build-prereq
0.0 s print-env-dashboard-summary
0.0 s print-app-summary
0.0 s deploy
0.0 s build
0.0 s prepare-env
0.0 s publish
PIPELINE SUCCEEDED
------------------------------------------------------------

aspire deploy を呼び出すと、Aspire CLI は各リソースのコンテナー イメージをビルドし(必要に応じて)ターゲット環境へプッシュしたうえで、AppHost に定義された構成に従ってリソースをデプロイします。

このコマンドに関する追加情報は、 aspire deploy のリファレンスドキュメントで確認できます。

デプロイ後、Aspire CLI は指定された出力パス(指定がない場合は既定の出力パス)に、デプロイ対象に応じた一連のファイルを書き出します。これには、Docker Compose ファイル、Kubernetes マニフェスト、クラウドプロバイダー固有の構成ファイルなどが含まれる場合があります。

  • ディレクトリaspire-output
    • .env
    • .env.Production
    • docker-compose.yaml

aspire-output ディレクトリには、生成された環境変数と Docker Compose の構成が含まれています。いちばん良い点は、開発者であるあなたがこれらのファイルを書いたり理解したりする必要がないことです!

.env.Production ファイルには、アプリのイメージ名が記載されています:

./aspire-output/.env.Production
# Container image name for apiservice
APISERVICE_IMAGE=apiservice:latest
# Default container port for apiservice
APISERVICE_PORT=8080
# Container image name for webfrontend
WEBFRONTEND_IMAGE=webfrontend:latest
# Default container port for webfrontend
WEBFRONTEND_PORT=8080

最後に、docker-compose.yaml ファイルには、API とフロントエンドの両方のサービスが定義されています:

./aspire-output/docker-compose.yaml
services:
env-dashboard:
image: "mcr.microsoft.com/dotnet/nightly/aspire-dashboard:latest"
expose:
- "18888"
- "18889"
networks:
- "aspire"
restart: "always"
apiservice:
image: "${APISERVICE_IMAGE}"
environment:
OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES: "true"
OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES: "true"
OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY: "in_memory"
ASPNETCORE_FORWARDEDHEADERS_ENABLED: "true"
HTTP_PORTS: "${APISERVICE_PORT}"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://env-dashboard:18889"
OTEL_EXPORTER_OTLP_PROTOCOL: "grpc"
OTEL_SERVICE_NAME: "apiservice"
expose:
- "${APISERVICE_PORT}"
networks:
- "aspire"
webfrontend:
image: "${WEBFRONTEND_IMAGE}"
environment:
OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES: "true"
OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES: "true"
OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY: "in_memory"
ASPNETCORE_FORWARDEDHEADERS_ENABLED: "true"
HTTP_PORTS: "${WEBFRONTEND_PORT}"
APISERVICE_HTTP: "http://apiservice:${APISERVICE_PORT}"
services__apiservice__http__0: "http://apiservice:${APISERVICE_PORT}"
APISERVICE_HTTPS: "https://apiservice:${APISERVICE_PORT}"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://env-dashboard:18889"
OTEL_EXPORTER_OTLP_PROTOCOL: "grpc"
OTEL_SERVICE_NAME: "webfrontend"
ports:
- "${WEBFRONTEND_PORT}"
depends_on:
apiservice:
condition: "service_started"
networks:
- "aspire"
networks:
aspire:
driver: "bridge"
  • ディレクトリaspire-output
    • .env
    • .env.Production
    • app.Dockerfile
    • docker-compose.yaml

aspire-output ディレクトリには、生成された環境変数、app.Dockerfile、および Docker Compose の構成が含まれています。いちばん良い点は、開発者であるあなたがこれらのファイルを自分で作成する必要がないことです!

.env.Production ファイルには、アプリのイメージ名が記載されています。:

./aspire-output/.env.Production
APP_IMAGE=app:5d592d0c1d2f417b0c14c4c4a9efb4f0760be8e4

app.Dockerfile は、Python をビルドし、さらに Uvicorn を使って React フロントエンドを提供するためのマルチステージ Dockerfile として生成されます:

./aspire-output/app.Dockerfile
ARG FRONTEND_IMAGENAME=frontend:50f0ed07a5b8f57b3213e99d96b2e8ff68a1d5d7
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
# Enable bytecode compilation and copy mode for the virtual environment
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy
WORKDIR /app
# Copy pyproject.toml to install dependencies
COPY pyproject.toml /app/
# Install dependencies and generate lock file
# Uses BuildKit cache mount to speed up repeated builds
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --no-install-project --no-dev
# Copy the rest of the application source and install the project
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --no-dev
FROM ${FRONTEND_IMAGENAME} AS frontend_stage
FROM python:3.13-slim-bookworm AS app
COPY --from=frontend_stage /app/dist /app/./static
# ------------------------------
# 🚀 Runtime stage
# ------------------------------
# Create non-root user for security
RUN groupadd --system --gid 999 appuser && useradd --system --gid 999 --uid 999 --create-home appuser
# Copy the application and virtual environment from builder
COPY --from=builder --chown=appuser:appuser /app /app
# Add virtual environment to PATH and set VIRTUAL_ENV
ENV PATH=/app/.venv/bin:${PATH}
ENV VIRTUAL_ENV=/app/.venv
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Use the non-root user to run the application
USER appuser
# Set working directory
WORKDIR /app
# Run the application
ENTRYPOINT ["uvicorn"]

最後に、docker-compose.yamlファイルには、API とフロントエンドの両方のサービスが定義されています:

./aspire-output/docker-compose.yaml
services:
env-dashboard:
image: "mcr.microsoft.com/dotnet/nightly/aspire-dashboard:latest"
expose:
- "18888"
- "18889"
networks:
- "aspire"
restart: "always"
app:
image: "${APP_IMAGE}"
command:
- "main:app"
- "--host"
- "0.0.0.0"
- "--port"
- "8000"
environment:
OTEL_TRACES_EXPORTER: "otlp"
OTEL_LOGS_EXPORTER: "otlp"
OTEL_METRICS_EXPORTER: "otlp"
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED: "true"
PORT: "8000"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://env-dashboard:18889"
OTEL_EXPORTER_OTLP_PROTOCOL: "grpc"
OTEL_SERVICE_NAME: "app"
ports:
- "8000"
networks:
- "aspire"
networks:
aspire:
driver: "bridge"

デプロイ後にアプリケーションが期待どおりに動作していることを確認するには、デプロイ先に応じた以下の手順に従ってください。

Docker Compose にデプロイすると、aspire deploy コマンドは各サービスが実行されている URL を表示します。デプロイ出力内の print-*-summary ステップを確認してください。ここには、WithExternalHttpEndpoints が構成されている各サービスの localhost URL が表示されます。

デプロイ出力には、次のような行が表示されます:

Aspire CLI - Deployment summary
14:28:35 (print-env-dashboard-summary) i [INF] Successfully deployed env-dashboard to http://localhost:54633.
14:28:35 (print-webfrontend-summary) i [INF] Successfully deployed webfrontend to http://localhost:54463.

Web ブラウザーを開き、Web フロントエンドとして表示されている URL(例: http://localhost:54463)にアクセスすると、デプロイされたアプリケーションを確認できます。

Docker Compose 上で実行中のデプロイ済み ASP.NET Core/Blazor アプリケーション

フロントエンドには、ASP.NET Core Blazor アプリケーションの天気予報データが表示されます。

デプロイ出力には、次のような行が表示されます:

Aspire CLI - Deployment summary
13:24:13 (print-env-dashboard-summary) i [INF] Successfully deployed env-dashboard to http://localhost:54633.
13:24:13 (print-app-summary) i [INF] Successfully deployed app to http://localhost:54463.

Web ブラウザーを開き、アプリとして表示されている URL(例: http://localhost:54463)にアクセスすると、デプロイされたアプリケーションを確認できます。

Docker Compose 上で実行中のデプロイ済み Python/React アプリケーション

フロントエンドには、美しい React テンプレートで天気予報データが表示されます。この例では、API サービスと React フロントエンドの両方が同じ Docker コンテナー内で実行されています。

リソースをクリーンアップする

Section titled “リソースをクリーンアップする”

After deploying your application, it’s important to clean up resources to avoid incurring unnecessary costs or consuming local system resources.

Docker Compose でデプロイした後のリソースをクリーンアップするには、次のコマンドを使用して実行中のコンテナーを停止・削除できます:

Aspire CLI - コンテナを停止し、削除
aspire do docker-compose-down-env

関連する基礎概念を詳しく知るには、Pipelines and app topologyをご覧ください。

初めての Aspire アプリを構築し、本番環境へデプロイしました。おめでとうございます! 🎉 次に思うのはきっとこうでしょう: 「これらすべてのサービスが本当に正しく連携して動くことを、どうやって確認するの?」 そこで登場するのが 統合テスト です。Aspire なら、サービス間通信やリソース依存関係を含むアプリケーション全体のスタックを簡単にテストできます。さっそく始めてみませんか? 最初のテストを書く