5
6

Docker 環境と C# ASP.NET Core で最小 API を実装する:MySQL

Last updated at Posted at 2023-08-24

Docker 環境と C# ASP.NET Core で最小 API を実装する:MySQL

こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 22.04 で C# ASP.NET Core Web アプリケーションを作成し、最小限の REST API を実装する方法を紹介します。
aspnet-core_and_mysql__on_docker.png

目的

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 クラスの作成

このシリーズの記事で、RDBMSNoSQL の両方で同じ API 操作を行います。そのため、ID フィールドは数値型ではなく文字列として定義しています。統一性を保ちつつ異なるデータストアで動作することを目指しています。ご了承ください。

Model クラスを作成します。

$ vim Model.cs

ファイルの内容

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

ファイルの内容

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

ファイルの内容

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

ファイルの内容

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

image.png
image.png

これらのツールを活用することにより、より手軽に API を操作することができます。

まとめ

WSL Ubuntu の Docker 環境で、C# ASP.NET Core の最小 API を実装することができました。

この記事の実装例は一つのアプローチに過ぎず、必ずしも正しい方法とは限りません。他にも多様な方法がありますので、さまざまな情報を照らし合わせて検討してみてください。

どうでしたか? WSL Ubuntu で、C# ASP.NET Core Web アプリケーションを手軽に起動することができます。ぜひお試しください。今後も .NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

推奨コンテンツ

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6