はじめに
備忘録です。Docker 上に nginx と ASP.NET Core の環境を構築します。
↓ 作った後に Docker 公式のサンプルがあることに気づいた ![]()
↓ こっちは Microsoft 公式です。
構成
ブラウザから nginx を経由(リバースプロキシ)して API にアクセスします。API は外部 API にアクセスし、その結果を加工してブラウザに返します。また Docker Compose という仕組みを使って、二つのコンテナをまとめて操作・管理します。
環境
- Visual Studio Community 2022
- Docker Desktop for Windows 4.70.0
手順
1. ASP.NET Core プロジェクトの作成
Visual Studio から ASP.NET Core Web API のプロジェクトテンプレートを作成します。
今回は WeatherForecastApi の名前にします。ASP.NET では WeatherForecast というモデルが、プロジェクト作成時にサンプル用のテンプレートとして自動生成されるので、それを流用する目論見です。
赤枠内「コンテナーのサポートを有効にする」をチェックします。今回 OS は Linux で、ビルドは Dockerfile です。
補足
Dockerfile とは Docker イメージの元となる設定ファイルです。「コンテナーのサポートを有効にする」にチェックすると Visual Studio でビルドした時、自動で ASP.NET イメージ作成 → コンテナ生成が実行されます。
2. ASP.NET Core コントローラーの作成
プロジェクトが作成されたら WeatherForecastController.cs を以下の内容に差し替えます。とりあえず動けばよいので、色々とガバガバです。
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace WeatherForecastApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public async Task<WeatherForecast> Get()
{
// API から天気情報を取得する。
using var httpClient = new HttpClient();
var data = await httpClient.GetFromJsonAsync<JsonElement>("https://api.open-meteo.com/v1/forecast?latitude=35.6895&longitude=139.6917¤t_weather=true");
// 必要な情報を抽出する。
double temp = 0;
if (data.TryGetProperty("current_weather", out var weather) && weather.TryGetProperty("temperature", out var temperature))
{
temp = temperature.GetDouble();
}
// モデルにマッピングして戻す。
var now = DateTime.UtcNow.AddHours(9); // 日本時間に変換。
return new WeatherForecast
{
Date = DateOnly.FromDateTime(now),
TemperatureC = (int)Math.Round(temp),
Summary = $"{now.TimeOfDay} - Tokyo current weather"
};
}
}
3. ASP.NET Core Dockerfile の確認
WeatherForecastController.cs を差し替える時に気付いたかもですが、プロジェクトに Visual Studio が自動生成した Dockerfile が含まれています。
中身はこんな感じです。デフォルトのままで大丈夫です。
# デバッグ コンテナーをカスタマイズする方法と、Visual Studio がこの Dockerfile を使用してより高速なデバッグのためにイメージをビルドする方法については、https://aka.ms/customizecontainer をご覧ください。
# このステージは、VS から高速モードで実行するときに使用されます (デバッグ構成の既定値)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
# このステージは、サービス プロジェクトのビルドに使用されます
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WeatherForecastApi/WeatherForecastApi.csproj", "WeatherForecastApi/"]
RUN dotnet restore "./WeatherForecastApi/WeatherForecastApi.csproj"
COPY . .
WORKDIR "/src/WeatherForecastApi"
RUN dotnet build "./WeatherForecastApi.csproj" -c $BUILD_CONFIGURATION -o /app/build
# このステージは、最終ステージにコピーするサービス プロジェクトを公開するために使用されます
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./WeatherForecastApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# このステージは、運用環境または VS から通常モードで実行している場合に使用されます (デバッグ構成を使用しない場合の既定)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WeatherForecastApi.dll"]
4. nginx の設定
ソリューション直下に nginx.conf を作成します。
nginx.conf に以下を記載します。
server {
listen 80;
location / {
proxy_pass http://weather-forecast-api:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
5. Docker Compose の作成
ソリューション直下に docker-compose.yml を作成します。
docker-compose.yml に以下を記載します。
version: '3.9'
services:
weather-forecast-api:
image: weather-forecast-api
build:
context: .
dockerfile: WeatherForecastApi/Dockerfile
# ports: ポートを Docker 外に公開しない
nginx:
image: nginx:latest
ports:
- "3000:80" # ホスト:3000 を nginx:80 にマッピングする
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- weather-forecast-api
6. コンテナの実行
PowerShell で docker-compose.yml のあるディレクトリに移動します。以下のコマンドで docker-compose をビルドします。
docker-compose up --build
補足
Docker Compose で作成したコンテナを停止・削除する場合は、以下のコマンドを実行します。
docker compose down
成功すると、以下のような表示になります。
Docker Desktop からも生成・実行されていることが確認できます。
↓ Containers 画面
↓ Images 画面
7. 動作確認
以下の URL にアクセスします。
以下のような Json が返ってきたら、成功です。
{
"date": "2020-02-01",
"temperatureC": 13,
"temperatureF": 55,
"summary": "17:28:40.2390666 - Tokyo current weather"
}
おわりに
簡単に環境構築できます。