
NET は、Webアプリ、Web API、クラウドのサーバーレス機能、モバイルアプリなど、多数のアプリを構築するための無料のオープンソース開発プラットフォームです。 .NET は、マイクロソフトと GitHub 上の .NET コミュニティによって管理されている汎用開発プラットフォームです。 クロスプラットフォームであり、Windows、macOS、Linux をサポートしており、デバイス、クラウド、埋め込み/IoT のシナリオで使用できます。
Docker は .NET コミュニティの間で非常に人気があります。 .NET Core は 、Docker コンテナーで簡単に実行できます。 .NET には、 自動メモリ管理、(ランタイム) ジェネリック型、 リフレクション、 非同期 、 同時実行、 ネイティブ相互運用など、開発を容易にするいくつかの機能があります。 何百万人もの開発者がこれらの機能を利用して、高品質のアプリケーションを効率的に構築しています。
アプリケーションのビルド
このチュートリアルでは、 Docker Compose を使用して .NET アプリケーションをコンテナー化する方法について説明します。 このブログで使用するアプリケーションは、 Postgresql データベースと通信するウェブアプリです。 ページが読み込まれると、Student テーブルに対して ID を持つレコードが照会され、ページに学生の名前が表示されます。
何が必要ですか?
始める
https://www.docker.com/get-started/ にアクセスして、Mac用のDockerデスクトップをダウンロードし、システムにインストールします。

インストールが完了したら、「Dockerデスクトップについて」をクリックして、システムで実行されているDockerのバージョンを確認します。

上記の手順に従うと、常に最新バージョンのDockerデスクトップがシステムにインストールされていることがわかります。
1. ターミナルで、次のコマンドを入力します
dotnet new webApp -o myWebApp --no-https
'dotnet new' コマンドは、テンプレートに基づいて .NET プロジェクトまたはその他の成果物を作成します。
ターミナルに出力が表示されます
The template ASP.NET Core Web App was created successfully. This template contains technologies from parties other than Microsoft, see https://aka.ms/aspnetcore/6.0-third-party-notices for details.
これにより、dotnet sdk に付属するテンプレートから新しい Web アプリケーションがブートストラップされます。 -o パラメーターは、アプリが格納される myWebApp という名前のディレクトリを作成します。
2. アプリケーションディレクトリに移動します
cd マイウェブアプリ
ファイルのリストがあります–
tree -L 2 . ├── Pages │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Index.cshtml │ ├── Index.cshtml.cs │ ├── Privacy.cshtml │ ├── Privacy.cshtml.cs │ ├── Shared │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── myWebApp.csproj ├── obj │ ├── myWebApp.csproj.nuget.dgspec.json │ ├── myWebApp.csproj.nuget.g.props │ ├── myWebApp.csproj.nuget.g.targets │ ├── project.assets.json │ └── project.nuget.cache └── wwwroot ├── css ├── favicon.ico ├── js └── lib 8 directories, 19 files
3. ターミナルで、次のコマンドを入力してアプリケーションを実行します
このコマンドは dotnet run 、ソース コードからアプリケーションを実行するための便利なオプションを提供します。
dotnet run –urls http://localhost:5000
アプリケーションは要求のリッスン port 5000 を開始します
# dotnet run Building... warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when the container is destroyed. warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'. info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /src
4. アプリケーションをテストする
curl コマンドを実行して、Web アプリケーションの接続をテストします。
# カール http://localhost:5000

5. アプリケーションをコンテナーに入れる
Dockerコンテナで同じアプリケーションを実行するために、次のコンテンツでDockerfileを作成しましょう。
FROM mcr.microsoft.com/dotnet/sdk as build COPY . ./src WORKDIR /src RUN dotnet build -o /app RUN dotnet publish -o /publish FROM mcr.microsoft.com/dotnet/aspnet as base COPY --from=build /publish /app WORKDIR /app EXPOSE 80 CMD ["./myWebApp"]
これは マルチステージ ドッカーファイルです。 ビルド・ステージでは、SDK イメージを使用してアプリケーションをビルドし、パブリッシュ・フォルダーに最終的な成果物を作成します。 次に、最終段階で、ビルド ステージからアプリ フォルダーに成果物をコピーし、ポート 80 を受信要求に公開し、アプリケーション myWebAppを実行するコマンドを指定します。
Dockerfile で実行するために必要なすべてのものを定義したので、このファイルを使用してイメージをビルドできます。 これを行うには、次のコマンドを実行する必要があります。
$ docker build -t mywebapp .
これで、docker imagesコマンドを使用して、イメージがマシンに存在することを確認できます。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mywebapp latest 6acc7ebf3a1d 25 seconds ago 210MB
この新しく作成されたイメージを実行するには、docker runコマンドを使用して、マップ先のポートと実行するイメージを指定できます。
$ドッカー実行--rm - p5000:80 mywebapp
- p 5000:80–これにより、ローカルマシンの http://localhost:5000 コンテナ内のポート80で実行されているアプリケーションが公開されます。--rm–このフラグは、実行後にコンテナをクリーンアップしますmywebapp–これは、コンテナで実行するイメージの名前です。
次に、ブラウザを起動し、http://localhost:5000 アドレスをアドレスバーに配置します

アプリケーションの更新
myWebApp と Postgresql は 2 つの別々のコンテナーで実行されるため、これはマルチコンテナー アプリケーションになります。
1.アプリがデータベースと通信できるようにするパッケージを追加します
ディレクトリを myWebapp に変更し、次のコマンドを実行します。
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
2. 学生モデルの作成
- プロジェクト フォルダーに Models フォルダーを作成する
- 次のコードを使用して.csモデル/学生を作成します。
using System;
using System.Collections.Generic;
namespace myWebApp.Models
{
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
}
3.次のコードを使用して「スクールコンテキスト」を作成します。
using Microsoft.EntityFrameworkCore;
namespace myWebApp.Data
{
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options) { }
public DbSet<Models.Student>? Students { get; set; }
}
}
4. スタートアップで DI に登録 SchoolContext します.cs
// You will need to add these using statements as well
using Microsoft.EntityFrameworkCore;
using myWebApp.Models;
using myWebApp.Data;
var builder = WebApplication.CreateBuilder(args);
// Add the SchoolContext here, before calling AddRazorPages()
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("SchoolContext")));
// Add services to the container.
builder.Services.AddRazorPages();
5. データベース接続文字列を 'appsettings.json に追加する'
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext":
"Host=db;Database=my_db;Username=postgres;Password=example"
}
}
6. テーブルに存在しない場合はブートストラップします。 Program.cs
using Microsoft.EntityFrameworkCore;
using myWebApp.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("SchoolContext")));
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
// add 10 seconds delay to ensure the db server is up to accept connections
// this won't be needed in real world application
System.Threading.Thread.Sleep(10000);
var context = services.GetRequiredService<SchoolContext>();
var created = context.Database.EnsureCreated();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
 
UI を更新する
'Pages/Index.cshtml' に以下を追加します。
<div class="row mb-auto"> <p>Student Name is @Model.StudentName</p> </div>
'Pages/Index.cshtml.cs' を更新します。 以下に示すように:
public class IndexModel : PageModel
{
public string StudentName { get; private set; } = "PageModel in C#";
private readonly ILogger<IndexModel> _logger;
private readonly myWebApp.Data.SchoolContext _context;
public IndexModel(ILogger<IndexModel> logger, myWebApp.Data.SchoolContext context)
{
_logger = logger;
_context= context;
}
public void OnGet()
{
var s =_context.Students?.Where(d=>d.ID==1).FirstOrDefault();
this.StudentName =
quot;{s?.FirstMidName} {s?.LastName}";
}
}
構成ファイル
Docker Compose へのエントリ ポイントは、通常は docker-compose.yml
プロジェクトディレクトリで、その中に新しいファイル docker-compose.yml を作成します。 次の内容を追加します。
services: db: image: postgres restart: always environment: POSTGRES_PASSWORD: example volumes: - postgres-data:/var/lib/postgresql/data adminer: image: adminer restart: always ports: - 8080:8080 app: build: context: . dockerfile: ./Dockerfile ports: - 5000:80 depends_on: - db volumes: postgres-data:
この作成ファイルの内容:
- この Compose の 2 つのサービスは、名前
dbとweb属性によって定義されます。 adminer サービスは、db にアクセスするためのヘルパーです - 属性を使用して
image定義された各サービスのイメージ名 - イメージによって
postgresPostgres サーバーが起動します。 environment属性は、PostGresサーバを初期化するための環境変数を定義します。POSTGRES_PASSWORDは、デフォルトのユーザー、 postgres、 パスワードを設定するために使用されます。 このユーザーには、接続文字列で my_db データベースに対するスーパーユーザー権限が付与されます。
- アプリ アプリケーションは、
db接続文字列で指定されたサービスを使用します - アプリ イメージは、プロジェクト ディレクトリ内の Dockerfile を使用してビルドされます
- ポート転送は、属性を使用して
ports実現されます。 depends_on属性を使用すると、サービス間の依存関係を表現できます。 この場合、Postgres はアプリの前に起動されます。 アプリケーションレベルのヘルスチェックは、引き続きユーザーの責任です。
アプリケーションを起動する
アプリケーション内のすべてのサービスは、次のコマンドを指定することで、デタッチモードで開始できます。
docker-compose up -d
代替の作成ファイル名は、オプションを使用して -f指定できます。
作成ファイルが存在する代替ディレクトリは、オプションを使用して -p 指定できます。
これにより、出力が次のように表示されます。
ocker compose up -d [+] Running 4/4 ⠿ Network mywebapp_default Created 0.1s ⠿ Container mywebapp-db-1 Started 1.4s ⠿ Container mywebapp-adminer-1 Started 1.3s ⠿ Container mywebapp-app-1 Started 1.8s 0
画像もダウンロードすると、出力が若干異なる場合があります。
開始されたサービスは、次のコマンドを使用して確認できます docker-compose ps:
ocker compose ps NAME COMMAND SERVICE STATUS PORTS mywebapp-adminer-1 "entrypoint.sh docke…" adminer running 0.0.0.0:8080->8080/tcp mywebapp-app-1 "./mywebapp" app running 0.0.0.0:5000->80/tcp mywebapp-db-1 "docker-entrypoint.s…" db running 5432/tcp
これにより、すべてのサービスと各サービス内のコンテナーの統合ビューが提供されます。
または、このアプリケーション内のコンテナーと、この Docker ホストで実行されている追加のコンテナーは、通常の docker container ls コマンドを使用して検証できます
docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f38fd86eb54f mywebapp_app "./mywebapp" About a minute ago Up About a minute 0.0.0.0:5000->80/tcp mywebapp-app-1 7b6b555585b9 adminer "entrypoint.sh docke…" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp mywebapp-adminer-1 5ea39a742206 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 5432/tcp mywebapp-db-1
サービスログはコマンドを使用して表示 docker-compose logs でき、次のようになります。
docker compose logs
mywebapp-adminer-1 | [Fri Apr 15 12:38:31 2022] PHP 7.4.16 Development Server (http://[::]:8080) started
mywebapp-db-1 |
mywebapp-db-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
mywebapp-db-1 |
mywebapp-db-1 | 2022-04-15 12:38:32.033 UTC [1] LOG: starting PostgreSQL 13.2 (Debian 13.2-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
mywebapp-db-1 | 2022-04-15 12:38:32.034 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
mywebapp-db-1 | 2022-04-15 12:38:32.034 UTC [1] LOG: listening on IPv6 address "::", port 5432
mywebapp-db-1 | 2022-04-15 12:38:32.056 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
mywebapp-db-1 | 2022-04-15 12:38:32.084 UTC [27] LOG: database system was shut down at 2021-11-13 22:52:29 UTC
mywebapp-db-1 | 2022-04-15 12:38:32.171 UTC [1] LOG: database system is ready to accept connections
mywebapp-app-1 | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
mywebapp-app-1 | Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
mywebapp-app-1 | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
mywebapp-app-1 | No XML encryptor configured. Key {e94371f0-08d1-43a0-b286-255e0005605c} may be persisted to storage in unencrypted form.
mywebapp-app-1 | info: Microsoft.Hosting.Lifetime[0]
mywebapp-app-1 | Now listening on: http://[::]:80
mywebapp-app-1 | info: Microsoft.Hosting.Lifetime[0]
mywebapp-app-1 | Application started. Press Ctrl+C to shut down.
mywebapp-app-1 | info: Microsoft.Hosting.Lifetime[0]
mywebapp-app-1 | Hosting environment: Production
mywebapp-app-1 | info: Microsoft.Hosting.Lifetime[0]
mywebapp-app-1 | Content root path: /app
アプリケーションの検証
アプリケーションにアクセスしてみましょう。 ブラウザーのアドレス バーに次のように入力します http://localhost:5000
データベースが空であるため、ページに学生名が表示されません。

アドレス http://localhost:8080 で新しいタブを開くと、ログインするように求められます。

ログイ ン my_db するためのユーザー名/パスワードとして postgres と 例 を使用します。ログインすると、次のように新しい学生レコードを作成できます。

次に、http://localhost:5000 でアプリページを更新すると、新しく追加された学生の名前が表示されます。

アプリケーションのシャットダウン
を使用してアプリケーションをシャットダウンします docker-compose down:
docker compose down [+] Running 4/4 ⠿ Container mywebapp-app-1 Removed 0.4s ⠿ Container mywebapp-adminer-1 Removed 0.3s ⠿ Container mywebapp-db-1 Removed 0.4s ⠿ Network mywebapp_default Removed 0.1s
これにより、各サービスのコンテナーが停止し、すべてのサービスが削除されます。 また、このアプリケーションの一部として作成されたネットワークもすべて削除されます。
結論
NETアプリケーションのコンテナ化と、dotnetを使用して2層のシンプルなWebアプリケーションを構築するためのdocker composeの使用を示しました。 現実世界のビジネスアプリケーションは、複数の類似したアプリケーション、すなわちで構成することができる。 Docker 作成ファイルで記述できるマイクロサービス アプリケーション。 チュートリアルの同じプロセスは、はるかに複雑なアプリケーションに適用できます。
