おーみんブログ

C#, ASP.NET Core, Unityが大好きです。

ASP.NET Core 5.0 MVC + SQLiteで作ったアプリをDocker上で動かしてみた!

はじめに

Dockerの勉強として、以前ASP.NET Coreで自作したアプリをDocker上で動かしてみました。

動作環境

  • Windows10 Pro
  • .NET Core SDK 5.0.205
  • Docker Version 19.03.12
  • Visual Studio 2019
C:\Work>ver
Microsoft Windows [Version 10.0.19042.1110]

C:\Work>dotnet --version
5.0.205

C:\Work>docker --version
Docker version 19.03.12, build 48a66213fe

Dockerfileの作成

続いてDockerfileを作成します。 Visual Studioを利用している方はプロジェクトを右クリック > 追加 > Dockerサポート > Linuxを選択するとテンプレートのDockerfileができますので利用すると良いかもしれません。

僕の場合はプロジェクトを分けているため、一部ファイルの内容を変更しています。

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
#ポート5000を利用するので追加します
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
#プロジェクトを分けており、一つ上の階層からDockerfileをビルドするのでパスをテンプレートから変更しています
COPY ["TestMaker/TestMaker.csproj", "TestMaker/"]
COPY ["DDD.Domain/DDD.Domain.csproj", "DDD.Domain/"]
RUN dotnet restore "TestMaker/TestMaker.csproj"
COPY . .
WORKDIR "/src/TestMaker"
RUN dotnet build "TestMaker.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TestMaker.dll"]

Dockerfileをビルドする

docker build -t testmaker -f "TestMaker/Dockerfile" .

※Dockerfileの一つ上の階層からビルドしました。

以下のようにイメージが作られていることを確認します。

C:\Work\TestMakerProject\TestMaker>docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
testmaker                         latest              addaa2f7e45d        16 minutes ago      263MB
<none>                            <none>              a353b688a51d        16 minutes ago      1.3GB
mcr.microsoft.com/dotnet/sdk      5.0                 fa98367f9017        3 days ago          631MB
mcr.microsoft.com/dotnet/aspnet   5.0                 44ffd671d35d        3 days ago          205MB

対象のイメージからコンテナを作成します。 ポートは8080としていますが、こちらは任意の値でいいかと思います。

C:\Work\TestMakerProject\TestMaker>docker run --rm -p 8080:5000 testmaker testmaker_onDocker
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 container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {7ab3713d-e0fb-40e3-9902-73b9ca437986} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

完成

http://localhost:8080 へアクセスすると無事に以下のようにアプリが正しく立ち上がることが確認できました!

終わりに

今回はDockerの勉強として以前作成したアプリをコンテナ化してみました! Linux上でも動くことを簡単に確認できるのでDockerは便利ですね。

アプリのソースコードは以下にあるのでもし参考になりそうでしたらどうぞ~ https://github.com/Oooooomin2/TestMaker

おまけ1

もしDockerfileが無事にビルドできたけど正常にアプリが立ち上がらない場合は以下の処理が抜けている可能性があります。 https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0#server-urls

※こちらの「おまけ」についてですが、別途ご教示をいただいた「おまけ2」の方より良い方法ですのでそちらをご確認くださいませ~! 今回はProgram.csに以下のコードを追記しています。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
             webBuilder.UseUrls("http://*:5000"); // <- 新たに追加
             webBuilder.UseStartup<Startup>();
        });

おまけ2

「おまけ」として書いた上記の内容について、お客様先(現在常駐している会社)の上司にもっと良い方法あるよ~!と2点教えてもらったので忘れないように追記します!

その1:ASPNETCORE_URLSを環境変数として渡す

上記の「おまけ」ではソースコード上にサーバのURLを記載していましたが、DockerfileにASPNETCore_URLを環境変数として渡す内容を追記することでアクセスが可能になります。上記で記載していたDockerfileの下から2行目に「ENV ASPNETCORE_URLS http://*:5000」を追記します。

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["TestMaker/TestMaker.csproj", "TestMaker/"]
COPY ["DDD.Domain/DDD.Domain.csproj", "DDD.Domain/"]
RUN dotnet restore "TestMaker/TestMaker.csproj"
COPY . .
WORKDIR "/src/TestMaker"
RUN dotnet build "TestMaker.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# ASPNETCORE_URLSを環境変数として渡す
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "TestMaker.dll"]

これでDockerfileをビルドして元の手順通りに進めてもブラウザからアクセスできるようになるかと思います。

その2:ASPNETCORE_ENVIRONMENTがProductionの場合はポート80でバインドされるので直接ポート80を指定する

環境変数ASPNETCORE_ENVIRONMENTはデフォルトでは"Production"となります。 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-5.0#environments

その際はポート80でバインドされるため、docker runの際に-pで5000:80を指定する。

C:\Work\TestMakerProject\TestMaker>docker run --rm -p 5000:80 testmaker testmaker_onDocker

※この場合は上記「その1:ASPNETCORE_URLSを環境変数として渡す」で記載したASPNETCORE_URLSはDockerfileに記載していません。

どちらもソースコードをいじらずに実現できるのでこちらの方が便利です!! 色々とご教示いただけるので本当に感謝です!(^^)!