Docker 環境と C# ASP.NET Core で最小 API を実装する:MySQL
こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 22.04 で C# ASP.NET Core Web アプリケーションを作成し、最小限の REST API を実装する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
ローカル環境の Ubuntu の Docker 環境で、Dockerfile からビルドした C# ASP.NET Core Web サービスのカスタムコンテナと MySQL データベースコンテナを起動します。
DLL ファイル形式のアプリをコンテナとして起動
実行環境
要素 | 概要 |
---|---|
terminal | ターミナル |
Ubuntu | OS |
Docker | コンテナ実行環境 |
API サービス コンテナ
要素 | 概要 |
---|---|
api-todo-aspnet-core | API サービス カスタムコンテナ |
dotnet | .NET 実行環境 |
kestrel | Web サーバー |
WebApp.dll | .NET アプリケーション |
データベース コンテナ
要素 | 概要 |
---|---|
mysql-todo | データベースコンテナ |
mysql | DB サーバー |
db_todo | データベース |
C# には本来厳格なコーディング規則がありますが、この記事では可読性のために、一部規則に沿わない表記方法を使用しています。ご注意ください。
技術トピック
ASP.NET Core とは?
こちらを展開してご覧いただけます。
ASP.NET Core
ASP.NET Core は、Microsoft が開発したオープンソースの Web アプリケーションフレームワークです。
キーワード | 内容 |
---|---|
クロスプラットフォームで動作します | ASP.NET Core は、Windows、Linux、macOS など、さまざまなオペレーティングシステム上で動作します。これにより、異なるプラットフォームで一貫性のあるアプリケーションを構築できます。 |
多様な用途に利用可能 | ASP.NET Core は、Web アプリケーション、API、マイクロサービス、IoT アプリケーションなど、様々な用途に適しています。これにより、幅広いプロジェクトに対応できます。 |
軽量なリクエスト処理パイプライン | ASP.NET Core は、高性能を提供するために最適化された軽量なリクエスト処理パイプラインを備えています。これにより、リクエストの処理効率が向上し、レスポンスタイムが短縮されます。 |
依存関係注入 | アプリケーション内のコンポーネント間の依存関係を注入する仕組みが組み込まれています。これにより、コードのテストや保守が容易になり、柔軟なアーキテクチャの構築が可能です。 |
テスト可能なアーキテクチャ | ASP.NET Core は、ユニットテストや統合テストをサポートするために設計されたアーキテクチャを提供します。これにより、品質の高いアプリケーションの開発が可能です。 |
多様な開発環境 | Visual Studio、VS Code、その他のエディターを使用して ASP.NET Core アプリケーションを開発できます。これにより、開発者は自分の好みやニーズに合った環境で作業できます。 |
開発環境
- Windows 11 Home 22H2 を使用しています。
WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
.NET SDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 23.0.1, build a5ee5b1
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する REST API の仕様
エンドポイント | HTTPメソッド | 説明 | リクエストBody | レスポンスBody |
---|---|---|---|---|
/todos | GET | すべての ToDo アイテムを取得します。 | None | ToDo アイテムの配列 |
/todos/complete | GET | 完了した ToDo アイテムを取得します。 | None | ToDo アイテムの配列 |
/todos/{id} | GET | ID で ToDo アイテムを取得します。 | None | ToDo アイテム |
/todos | POST | 新しい ToDo アイテムを追加します。 | ToDo アイテム | ToDo アイテム |
/todos/{id} | PUT | 既存の ToDo アイテムを更新します。 | ToDo アイテム | None |
/todos/{id} | DELETE | ID で ToDo アイテムを削除します。 | None | None |
データベース コンテナの起動
こちらの記事で、ToDo アプリ用の RDBMS データベースを作成し、Docker コンテナとして起動する手順をご確認いただけます。
データベース コンテナが起動していることを確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63a3acec271c mysql-base "docker-entrypoint.s…" 20 hours ago Up 3 hours 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-todo
コンテナ間通信するために net-todo という Docker ネットワークを予め作成しています。ご注意ください。
REST API を実装する手順
プロジェクトルートフォルダに移動
プロジェクトルートフォルダに移動します。
※ ~/tmp/restapi-aspnet-core をプロジェクトフォルダとします。
$ cd ~/tmp
プロジェクトの作成
プロジェクトを作成します。
$ dotnet new web -n restapi-aspnet-core
プロジェクトフォルダに移動します。
$ cd ~/tmp/restapi-aspnet-core
csproj ファイルのリネーム
こちらの作業は必須ではありません。最終的にアプリを WebApp.dll という名前でビルドするために行っています。デフォルトの名前で問題ない場合にはそのまま読み進めて下さい。
$ mv restapi-aspnet-core.csproj WebApp.csproj
ライブラリの追加
Entity Framework Core パッケージを NuGet で取得します。
$ dotnet add package MySql.EntityFrameworkCore
この記事では データベースに MySQL を使用する為、MySQL 用のライブラリを取得しています。
Model クラスの作成
このシリーズの記事で、RDBMS と NoSQL の両方で同じ API 操作を行います。そのため、ID フィールドは数値型ではなく文字列として定義しています。統一性を保ちつつ異なるデータストアで動作することを目指しています。ご了承ください。
Model クラスを作成します。
$ vim Model.cs
ファイルの内容
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using static System.Environment;
using Microsoft.EntityFrameworkCore;
// ToDo エンティティに対する DbContext クラス
public class TodoDb : DbContext {
public DbSet<Todo> Todos => Set<Todo>();
public TodoDb(DbContextOptions<TodoDb> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseMySQL(
$"server={GetEnvironmentVariable("DB_HOST")}; " +
$"port={GetEnvironmentVariable("DB_PORT")}; " +
$"database={GetEnvironmentVariable("DB_NAME")}; " +
$"user={GetEnvironmentVariable("DB_USER")}; " +
$"password={GetEnvironmentVariable("DB_PASSWORD")}"
);
}
}
// ToDo エンティティを表すクラス
[Table("todos")]
public class Todo {
// RDBMS 本来の int 型のキー:API 入出力の JSON にはマッピングしない
[JsonIgnore]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key][Column("id")] public int _rdbms_id { get; set; }
// string 型の ID を定義:RDBMS 側にはマッピングしない
[NotMapped] public string id {
get { return _rdbms_id.ToString(); }
set { _rdbms_id = int.Parse(value); }
}
[Column("content")] public string? content { get; set; }
[Column("created_date")] public DateTime? created_date { get; set; }
[Column("completed_date")] public DateTime? completed_date { get; set; }
}
説明を開きます。
TodoDb クラス
要素 | 説明 |
---|---|
DbContext | DbContext クラスを継承しています。これは Entity Framework Core のコンテキストクラスであり、データベースとの接続やクエリの実行を行います。 |
DbSet<Todo> | Todos プロパティは DbSet<Todo> 型のプロパティです。これは、エンティティセットとして操作したいエンティティのコレクションを表します。 |
OnConfiguring | コンストラクタ内で、データベース接続情報を設定しています。OnConfiguring メソッドで MySQL データベースの接続文字列を構築しています。 |
Todo クラス
要素 | 説明 |
---|---|
Todo | ToDo アイテムを表すエンティティクラスです。 |
Table("todos") | このクラスが "todos" テーブルとマッピングされることを示す属性です。 |
DatabaseGenerated | _rdbms_id プロパティが自動生成されることを示しています。これにより、データベースの主キーが自動的に生成されます。 |
Key | エンティティの主キーを指定するための属性です。 |
Column("id") | データベーステーブルの列とエンティティプロパティをマッピングするための属性です。 |
JsonIgnore | _rdbms_id プロパティが JSON シリアライズされないようにしています。これにより、API 入出力時に ID が表示されなくなります。 |
NotMapped | JSON シリアライズ時に _rdbms_id プロパティを文字列として表現するためのプロパティです。データベースにはマッピングされません。 |
id | _rdbms_id プロパティを介してマッピングされる、エンティティの識別子を表します。JSON シリアライゼーション時には無視されます。 |
_rdbms_id | RDBMS 本来の int 型のキーとして使用され、JSON シリアライズ時には無視されます。 |
content、created_date、completed_date | それぞれ ToDo アイテムの内容、作成日時、完了日時を表します。 |
Program クラスの修正
Program クラスを修正します。
$ vim Program.cs
ファイルの内容
using Microsoft.EntityFrameworkCore;
// app オブジェクトを作成します。
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors();
builder.Services.AddDbContext<TodoDb>();
WebApplication app = builder.Build();
// CORS 設定:適切に修正してください。
app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
// ルートグループを作成します。
RouteGroupBuilder routeGroupTodos = app.MapGroup("/todos");
// すべての ToDo アイテムを取得します。
routeGroupTodos.MapGet("/", getAllTodos);
static async Task<IResult> getAllTodos(TodoDb db) {
return TypedResults.Ok(
await db.Todos.ToArrayAsync()
);
}
// 完了した ToDo アイテムを取得します。
routeGroupTodos.MapGet("/complete", getCompleteTodos);
static async Task<IResult> getCompleteTodos(TodoDb db) {
return TypedResults.Ok(
await db.Todos.Where(x => x.completed_date != null).ToListAsync()
);
}
// ID で ToDo アイテムを取得します。
routeGroupTodos.MapGet("/{id}", getTodo);
static async Task<IResult> getTodo(string id, TodoDb db) {
return await db.Todos.FindAsync(int.Parse(id))
is Todo todo
? TypedResults.Ok(todo)
: TypedResults.NotFound();
}
// 新しい ToDo アイテムを追加します。
routeGroupTodos.MapPost("/", createTodo);
static async Task<IResult> createTodo(Todo todo, TodoDb db) {
todo.created_date = DateTime.Now;
db.Todos.Add(todo);
await db.SaveChangesAsync();
return TypedResults.Created($"/todos/{todo.id}", todo);
}
// 既存の ToDo アイテムを更新します。
routeGroupTodos.MapPut("/{id}", updateTodo);
static async Task<IResult> updateTodo(string id, Todo todo, TodoDb db) {
Todo? target = await db.Todos.FindAsync(int.Parse(id));
if (target is null) {
return TypedResults.NotFound();
}
target.content = todo.content;
target.completed_date = todo.completed_date;
await db.SaveChangesAsync();
return TypedResults.NoContent();
}
// ID で ToDo アイテムを削除します。
routeGroupTodos.MapDelete("/{id}", deleteTodo);
static async Task<IResult> deleteTodo(string id, TodoDb db) {
if (await db.Todos.FindAsync(int.Parse(id)) is Todo todo) {
db.Todos.Remove(todo);
await db.SaveChangesAsync();
return TypedResults.NoContent();
}
return TypedResults.NotFound();
}
app.Run();
説明を開きます。
要素 | 説明 |
---|---|
Task<IResult> | 非同期操作の結果を表す型で、非同期メソッドの戻り値として使用されます。 |
IResult | API エンドポイントの処理結果を表すインターフェースです。成功や失敗などの状態を持ち、HTTP レスポンスを適切に生成するための情報を提供します。 |
TypedResults | API エンドポイントのレスポンスを構築するためのヘルパークラスです。TypedResults.Ok(data) は成功した場合のレスポンスを生成し、TypedResults.NotFound() はリソースが見つからなかった場合のレスポンスを生成するなど、一般的な API レスポンスを簡単に生成できます。 |
Cors 設定 | app.UseCors(...) で定義されており、異なるドメイン間のリクエストを許可するための設定です。AllowAnyOrigin() はどのオリジンからのリクエストでも許可することを意味し、AllowAnyHeader() と AllowAnyMethod() はすべてのヘッダーと HTTP メソッドを許可することを意味します。 |
アプリのビルドと起動
環境変数を作成します。
export DB_HOST=localhost
export DB_PORT=3306
export DB_NAME=db_todo
export DB_USER=root
export DB_PASSWORD=password
この環境変数が一時的なものであることに注意してください。
アプリを起動します。
※ アプリを停止するときは ctrl + C を押します。
この例では、アプリがリッスンするポート番号を5000に設定して起動しています。
$ dotnet run --urls http://localhost:5000
ここまでの手順で、Ubuntu でアプリの DLL ファイルを起動することができました。
アプリの動作確認
別ターミナルから curl コマンドで確認します。
必要な場合、jq をインストールします。
$ sudo apt update
$ sudo apt install jq
GET: /todos エンドポイントの動作確認
すべての ToDo アイテムを取得します。
$ curl -s http://localhost:5000/todos | jq '.'
レスポンス
[
// 省略
{
"id": "3",
"content": "運動する",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": "2023-08-16T05:25:04Z"
},
{
"id": "4",
"content": "本を読む",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": null
},
{
"id": "5",
"content": "請求書を支払う",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": null
},
// 省略
すべての ToDo アイテムを取得できています。
GET: /todos/complete エンドポイントの動作確認
完了した ToDo アイテムを取得します。
$ curl -s http://localhost:5000/todos/complete | jq '.'
レスポンス
[
{
"id": "1",
"content": "食材を買う",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": "2023-08-16T05:25:04Z"
},
{
"id": "2",
"content": "報告書を仕上げる",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": "2023-08-16T05:25:04Z"
},
{
"id": "3",
"content": "運動する",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": "2023-08-16T05:25:04Z"
}
]
完了した ToDo アイテムを取得できています。
GET: /todos/{id} エンドポイントの動作確認
ID で ToDo アイテムを取得します。
$ curl -s http://localhost:5000/todos/8 | jq '.'
レスポンス
{
"id": "8",
"content": "コードを書く",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": null
}
ID で ToDo アイテムを取得できています。
POST: /todos エンドポイントの動作確認
新しい ToDo アイテムを追加します。
$ curl -s -X POST http://localhost:5000/todos \
-H 'Content-Type: application/json; charset=utf-8' \
-d \
'{
"content": "昼寝をする"
}' | jq '.'
レスポンス
{
"id": "9",
"content": "昼寝をする",
"created_date": "2023-08-16T16:04:23.1245781+09:00",
"completed_date": null
}
新しい ToDo アイテムが追加できています。
PUT: /todos/{id} エンドポイントの動作確認
既存の ToDo アイテムを更新します。
$ curl -s -X PUT http://localhost:5000/todos/9 \
-H 'Content-Type: application/json; charset=utf-8' \
-d \
'{
"content": "窓を開ける"
}' | jq '.'
レスポンス
None (※なし)
レスポンスは None ですが、DB のテーブルを確認すると対象のレコードが更新されています。
DELETE: /todos/{id} エンドポイントの動作確認
ID で ToDo アイテムを削除します。
$ curl -s -X DELETE http://localhost:5000/todos/9 | jq '.'
レスポンス
None (※なし)
レスポンスは None ですが、DB のテーブルを確認すると対象のレコードが削除されています。
ここまでの手順で、最小限の CRUD 操作を行う REST API をアプリに実装できました。
コンテナイメージの作成
Dockerfile を作成します。
$ vim Dockerfile
ファイルの内容
# build the app.
FROM mcr.microsoft.com/dotnet/sdk:7.0-bookworm-slim AS build-env
# set the working dir.
WORKDIR /App
# copy source code to the working dir.
COPY . .
# restore as distinct layers.
RUN dotnet restore WebApp.csproj
# build and publish the app as a release.
RUN dotnet publish WebApp.csproj -c Release -o out
# set up the container.
FROM mcr.microsoft.com/dotnet/aspnet:7.0-bookworm-slim
# set the working dir.
WORKDIR /App
# copy the built app from the build-env.
COPY --from=build-env /App/out .
# command to run the app.
ENTRYPOINT ["dotnet","WebApp.dll"]
説明を開きます。
要素 | 説明 |
---|---|
FROM mcr.microsoft.com/dotnet/sdk:7.0-bookworm-slim AS build-env | ビルド環境として .NET SDK イメージを使用します。 |
WORKDIR /App | 作業ディレクトリを /App に設定します。 |
COPY . . | ソースコードを作業ディレクトリにコピーします。 |
RUN dotnet restore WebApp.csproj | プロジェクトの依存関係を復元します。 |
RUN dotnet publish WebApp.csproj -c Release -o out | プロジェクトをリリースモードでビルド・パブリッシュします。 |
FROM mcr.microsoft.com/dotnet/aspnet:7.0-bookworm-slim | 実行環境として ASP.NET Core ランタイムイメージを使用します。 |
WORKDIR /App | 作業ディレクトリを /App に設定します。 |
COPY --from=build-env /App/out . | ビルド環境からビルドされたアプリケーションをコピーします。 |
ENTRYPOINT ["dotnet","WebApp.dll"] | コンテナが起動されたときに実行されるコマンドを設定します。 |
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
コンテナイメージをビルドします。
$ docker build \
--no-cache \
--tag api-todo-aspnet-core:latest .
コンテナイメージを確認します。
$ docker images | grep api-todo-aspnet-core
api-todo-aspnet-core latest e2393d2c9e41 21 seconds ago 231MB
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
コンテナを起動
ローカルでコンテナを起動します。
※ コンテナを停止するときは ctrl + C を押します。
コンテナ間通信するために net-todo という Docker ネットワークを予め作成しています。ご注意ください。
$ docker run --rm \
--publish 5000:80 \
--name api-local \
--net net-todo \
--env DB_HOST=mysql-todo \
--env DB_PORT=3306 \
--env DB_NAME=db_todo \
--env DB_USER=root \
--env DB_PASSWORD=password \
api-todo-aspnet-core
ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナを起動することができました。
コンテナの動作確認
別ターミナルから curl コマンドで確認します。
※ ID で ToDo アイテムを取得します。
$ curl -s http://localhost:5000/todos/8 | jq '.'
レスポンス
{
"id": "8",
"content": "コードを書く",
"created_date": "2023-08-16T05:25:04Z",
"completed_date": null
}
ここまでの手順で、ターミナルにレスポンスが表示され、JSON データを取得することが出来ました。
コンテナの状態を確認してみます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c498f9ce9b36 api-todo-aspnet-core "dotnet WebApp.dll" 2 minutes ago Up 2 minutes 0.0.0.0:5000->80/tcp, :::5000->80/tcp api-local
63a3acec271c mysql-base "docker-entrypoint.s…" 18 hours ago Up 34 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-todo
コンテナに接続
別ターミナルからコンテナに接続します。
$ docker exec -it api-local /bin/bash
コンテナに接続後にディレクトリを確認します。
※ コンテナから出るときは ctrl + D を押します。
# pwd
/App
# ls -lah
total 11M
drwxr-xr-x 1 root root 4.0K Aug 17 01:38 .
drwxr-xr-x 1 root root 4.0K Aug 17 01:40 ..
-rwxr--r-- 1 root root 3.2M Oct 19 2021 BouncyCastle.Crypto.dll
-rwxr--r-- 1 root root 400K Oct 26 2022 Google.Protobuf.dll
-rwxr--r-- 1 root root 79K Jan 6 2023 K4os.Compression.LZ4.Streams.dll
-rwxr--r-- 1 root root 66K Jan 6 2023 K4os.Compression.LZ4.dll
-rwxr--r-- 1 root root 13K Nov 8 2022 K4os.Hash.xxHash.dll
-rwxr--r-- 1 root root 34K Mar 15 18:09 Microsoft.EntityFrameworkCore.Abstractions.dll
-rwxr--r-- 1 root root 1.8M Mar 15 18:09 Microsoft.EntityFrameworkCore.Relational.dll
-rwxr--r-- 1 root root 2.0M Mar 15 18:09 Microsoft.EntityFrameworkCore.dll
-rwxr--r-- 1 root root 23K Nov 15 2019 Microsoft.Win32.SystemEvents.dll
-rwxr--r-- 1 root root 1.2M Jul 12 03:30 MySql.Data.dll
-rwxr--r-- 1 root root 241K Jul 12 03:30 MySql.EntityFrameworkCore.dll
-rwxr--r-- 1 root root 372K Nov 20 2017 System.Configuration.ConfigurationManager.dll
-rwxr--r-- 1 root root 141K Sep 18 2018 System.Drawing.Common.dll
-rwxr--r-- 1 root root 25K Jul 19 2017 System.Security.Cryptography.ProtectedData.dll
-rwxr--r-- 1 root root 91K Nov 15 2019 System.Security.Permissions.dll
-rwxr--r-- 1 root root 26K Nov 15 2019 System.Windows.Extensions.dll
-rwxr-xr-x 1 root root 177K Aug 17 01:38 WebApp
-rw-r--r-- 1 root root 28K Aug 17 01:38 WebApp.deps.json
-rw-r--r-- 1 root root 16K Aug 17 01:38 WebApp.dll
-rw-r--r-- 1 root root 22K Aug 17 01:38 WebApp.pdb
-rw-r--r-- 1 root root 537 Aug 17 01:38 WebApp.runtimeconfig.json
-rwxr--r-- 1 root root 413K Apr 6 12:25 ZstdSharp.dll
-rw-r--r-- 1 root root 278 Aug 16 13:23 appsettings.json
drwxr-xr-x 5 root root 4.0K Aug 17 01:38 runtimes
-rw-r--r-- 1 root root 482 Aug 17 01:38 web.config
top コマンドで状況を確認します。
# apt update
# apt install procps
# top
top - 01:43:52 up 2:36, 0 user, load average: 0.07, 0.08, 0.08
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.9 us, 0.3 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 7897.1 total, 1768.5 free, 3284.8 used, 3154.1 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 4612.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 262.3g 117172 95676 S 0.0 1.4 0:01.52 dotnet
44 root 20 0 4188 3416 2908 S 0.0 0.0 0:00.02 bash
235 root 20 0 8560 4456 2580 R 0.0 0.1 0:00.00 top
コンテナの情報を表示してみます。
# cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
このコンテナは Debian GNU/Linux をベースに作成されています。つまり、Debian GNU/Linux と同じように扱うことができます。
おまけ:Swagger 装備
ライブラリの追加
Swagger 関連パッケージを NuGet で取得します。
$ dotnet add package Swashbuckle.AspNetCore
$ dotnet add package Microsoft.AspNetCore.OpenApi
Program クラスの修正
Program クラスを修正します。
$ vim Program.cs
ファイルの内容
using Microsoft.EntityFrameworkCore;
// app オブジェクトを作成します。
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors();
builder.Services.AddDbContext<TodoDb>();
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
WebApplication app = builder.Build();
// CORS 設定:適切に修正してください。
app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
+ // Swagger 設定
+ app.UseSwagger();
+ app.UseSwaggerUI();
// 以前のコード
app.Run();
Swagger を確認
Web ブラウザで Swagger の URL を確認します。
http://localhost:5000/Swagger
これらのツールを活用することにより、より手軽に API を操作することができます。
まとめ
WSL Ubuntu の Docker 環境で、C# ASP.NET Core の最小 API を実装することができました。
この記事の実装例は一つのアプローチに過ぎず、必ずしも正しい方法とは限りません。他にも多様な方法がありますので、さまざまな情報を照らし合わせて検討してみてください。
どうでしたか? WSL Ubuntu で、C# ASP.NET Core Web アプリケーションを手軽に起動することができます。ぜひお試しください。今後も .NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ