18
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ASP.NET Core のWebアプリケーションを docker-compose で Dockerアプリケーション として構築する

Last updated at Posted at 2020-01-02

概要

ASP.NET CoreのサンプルWebアプリケーションを題材として、docker-compose による Dockerアプリケーション の動作環境を構築する例を紹介します。

更新履歴

  • 2023/07/01:各種、ソフトウェア・ミドルウェアのバージョンを更新しました。

環境

  • Windows11
  • Visual Studio 2022
  • ASP.NET Core (.NET6)
  • Docker for Windows

サンプルアプリケーション

題材にしたサンプルアプリケーションです。
https://github.com/tYoshiyuki/dotnet-core-web-sample

単純なToDoのWebアプリケーションです。トランザクションデータはデータベース (SQL Server) に保存しています。
これを Docker を利用して コンテナ化 してみましょう。

システム構成

今回は、Docker for Windows を利用して、ローカルPC上にDocker環境を構築します。ローカル開発時は、IIS Express と LocalDB を利用して開発を行いましたが、これを変更します。フロントエンドは Nginx、データベースは SQL Express の Dockerイメージを利用し、アプリケーションのコンテナを含めて3つのコンテナで構築します。構成イメージは下記の通りです。

image.png

通常、ASP.NET Core アプリケーションを IIS でホストする場合には、ASP.NET Coreのミドルウェアにより、アプリケーションはIISと統合的に動作します。Nginxをリバースプロキシとしてフロントエンドに構築する場合は、ASP.NET Core アプリケーションは Kestrel で動作させておき、そこに対してHTTP通信を転送します。

Dockerfile

1. ASP.NET Core アプリケーション

まずは、ASP.NET Core アプリケーションをコンテナ化するために、Dockerfileを作成します。Visual Studio > プロジェクト > 右クリック Dockerサポート > ターゲットOS Linux から追加できる Dockerfile をベースにして編集を行います。

Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0.1-bullseye-slim AS base

WORKDIR /app
# EXPOSE 80
# EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0.101-bullseye-slim AS build
WORKDIR /src
COPY ["DotNetCoreWebSample.Web.csproj", "./"]
RUN dotnet restore "DotNetCoreWebSample.Web.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "DotNetCoreWebSample.Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "DotNetCoreWebSample.Web.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "DotNetCoreWebSample.Web.dll"]

Dockerfileの解説についてはここでは省略しますが、デフォルトでマルチステージビルドを行い、Dockerイメージサイズを削減するような設定になっています。ポイントとしては [ENV ASPNETCORE_URLS http://*:5000] で、Kestrelが待ち受けを行うポート番号を指定している部分です。後々、Nginxでリクエストを転送する際における、送信先ポート番号になります。

また、ソースコードも公式ドキュメントに従い、若干ですが変更を行います。
https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-3.1

Startup.cs
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // ・・・一部省略・・・

            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            // ・・・一部省略・・・

リバースプロキシを経由した際における、X-Forwarded-For・X-Forwarded-Protoヘッダの転送を行うようにします。
これは、IIS上でASP.NET Coreアプリケーションを動作させた場合は、既定で有効になっているので注意が必要です。

公式ドキュメントにも記載があるため、目を通しておくことをお勧めします。
https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1

2. Nginx

次にNginx用の設定を作成します。

Dockerfile
FROM nginx:latest

COPY ./nginx.conf /etc/nginx/nginx.conf

COPY ./site.conf.template /etc/nginx/templates/site.conf.template

CMD [ "nginx", "-g", "daemon off;" ]
nginx.conf
worker_processes 1;

events { worker_connections 1024; }

http {
    sendfile on;

    include /etc/nginx/conf.d/site.conf;
}
site.conf.template
upstream web-app {
    server ${BACKEND_HOST};
}

server {
    listen 80;
    server_name $hostname;
    location / {
        proxy_pass         http://web-app;
        proxy_redirect     off;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   X-Forwarded-Host $server_name;
    }
}

nginx 1.19 の Dockerイメージ より、環境変数を template を用いることで注入することが出来るようになりました。
この機能を用いて、アプリケーションサーバの宛先 (BACKEND_HOST) を外部注入可能にしておきます。これに関しては、後ほど docker-compose.yml で解説を行います。

3. SQL Server Express

最後に SQL Server Express です。サンプルアプリケーションの機能としてはLocalDBで十分なのですが、公式にDockerイメージが存在しないようなので、SQL Server Expressを利用します。尚、実際にはDBデータを永続化する設定が必要ですが、今回は省略しています。

Dockerfile
FROM mcr.microsoft.com/mssql/server:2017-latest-ubuntu

docker-compose.yml

作成した各コンテナを docker-compose を利用して起動してみましょう。

docker-compose.yml

version: '3.4'

services:
  app:
    build:
      context: ./DotNetCoreWebSample.Web
      dockerfile: Dockerfile
    environment:
      ConnectionStrings__DefaultConnection: "Server=sqlexpress;Database=master;User ID=sa;Password=P@ssw0rd;initial catalog=dotnetcorewebsample;MultipleActiveResultSets=True;App=EntityFramework;"
    expose:
      - 5000
    depends_on:
      - sqlexpress

  sqlexpress:
    build:
      context: ./docker/sqlexpress
      dockerfile: Dockerfile
    environment:
      MSSQL_PID: "Express"
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "P@ssw0rd"
    ports:
      - 1433:1433

  web:
    build:
      context: ./docker/nginx
    environment:
      BACKEND_HOST: "app:5000"  
    ports: 
      - 80:80

記載が長いですが、何点かポイントを解説します。

まず、 ConnectionStrings__DefaultConnection: "Server=sqlexpress;Database=master;User ID=sa;Password=P@ssw0rd;initial catalog=dotnetcorewebsample;MultipleActiveResultSets=True;App=EntityFramework;" の部分は、SQL Server Express への接続先情報を設定しています。コンテナ起動時に appsettings.json で設定している内容を上書きします。ネストされたJSONの要素 (ConnectionStrings > DefaultConnection) を表現する場合に、アンダーバー2つ (__) を使用します。

BACKEND_HOST: "app:5000" の部分で、ASP.NET Core アプリケーションへの送信先を設定しています。docker-composeでは、サービス名で各コンテナの宛先を解決出来るため、上記のような設定になります。

docker-composeコマンドを実行し、各コンテナを起動します。

docker-compose up -d

実行後 http://localhost でアクセスし、動作を確認します。

image.png

まとめ

docker-composeを用いて、Dockerアプリケーションを構築する例を紹介させていただきました。
クロスプラットフォームを特徴とする .NET Core なので、Dockerを用いた開発も盛り上がると良いなと思います。

ASP.NET Core と Azure で開発する場合、Web Apps や SQL Database といった優れた PaaS を利用することで、手軽にスケーラブルなアプリケーションを構築することが出来ます。そのため、Docker のようなコンテナ技術を利用するシーンは、あまり多く無いかも知れません。

ですが、ASP.NET Coreのアプリケーションをコンテナ化することで、AWS や GCP といった別クラウドサービスへの転用や、Kubernetesに代表される コンテナ オーケストレーション の恩恵を受けることが出来るようになります。システムアーキテクチャの選択肢として、考慮する価値は十分にあるのではないのでしょうか。

18
21
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
18
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?