今回は ASP.NET Core MVC で試したが ASP.NET Core WebAPI プロジェクトでも同様のはず
TL;DR
Microsoft のリファレンスにあるステップどうりに進めればOK。英語で読むことを推奨。
Windowsの手順もこっちに十分まとまっています。
- Docker images for ASP.NET Core
- Hosting ASP.NET Core images with Docker over HTTPS
- Hosting ASP.NET Core images with Docker Compose over HTTPS
なぜ書いたのか
- Microsoft のリファレンスがあちこちに飛び散っていて把握しづらかった
- 後述する自己署名証明書の部分で詰まって悲しかった
- 今回の作業したリポジトリは以下に格納してあります(作業中のリポジトリなので記事の部分以外のものが今後足されるかも)
対象環境など
- ローカル環境(Mac)
- 無いと思いますが本番環境などに利用する際は証明書など適宜準備して下さい
- .NET Core 3.1
- 想定ディレクトリ構成
- myapp
- Controllers
- Models
- Views
- wwwroot
- appsettings.Development.json
- myapp.csproj
- Program.cs
- Startup.cs
- Dockerfile
- docker-compose.yml
- myapp
手順立ててやっていこう
一気にやろうとするとつまづいた時に戸惑うので順序立ててやっていくのは大事
ステップ 1
ASP.NET MVC アプリなどを新規作成し、 dotnet run
で起動確認
% cd myapp
% dotnet new mvc -o .
% dotnet run
※せっかく Docker 用意すんのにローカルPCに .NET Core SDK いるんかい! という方は飛ばしてもOK
ステップ 2
以下のような Dockerfile
を用意し HTTP接続による Docker コンテナでの起動確認をしていく
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY ./myapp.csproj .
RUN dotnet restore
# copy everything else and build app
COPY . ./
WORKDIR /app
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.8-buster-slim AS runtime
WORKDIR /app
COPY --from=build /app/out ./
ENTRYPOINT ["dotnet", "myapp.dll"]
なお、 上記 Dockerfile は myapp.csprj と同一階層に Dockerfile を置いたときのサンプル。
Microsft のリファレンスでは以下のようなディレクトリ構造でのサンプルになっている
(.NET Core はプロジェクトを細分化してソリューションファイルでまとめて管理する開発方法が推奨されている? ので Microsoft のサンプルが正しいのだが今回は同一階層でやりたかった)
- myapp
- aspnetapp
- aspnetapp.csproj
- aspnetapp
- myapp.sln
- Dockerfile
- docker-compose.yml
Dockerfile を作成したら以下コマンドでHTTP接続による起動確認
% docker build -t myapp_image .
% docker run -it --rm -p 5000:80 --name myapp myapp_image
ステップ 3
dotnet dev-certs
コマンドを使用して自己署名証明書を準備する。
% dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p { password here }
% dotnet dev-certs https --trust
{ password here }
の部分を各々のパスワードに設定のこと。
本筋とは関係ないが今回ここの設定でミス( { passward hogefuga }
など{}つきにしまっていた)していることに気づかず
自己署名証明書を使って立ち上げた時に以下の様なエラーが出て起動しなかった。
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 {eebd890e-0312-4174-bb70-97f7873df627} may be persisted to storage in unencrypted form.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
Interop+Crypto+OpenSslCryptographicException: error:2006D080:BIO routines:BIO_new_file:no such file
at Interop.Crypto.CheckValidOpenSslHandle(SafeHandle handle)
at Internal.Cryptography.Pal.OpenSslX509CertificateReader.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert(ConfigurationReader configReader)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
Unhandled exception. Interop+Crypto+OpenSslCryptographicException: error:2006D080:BIO routines:BIO_new_file:no such file
at Interop.Crypto.CheckValidOpenSslHandle(SafeHandle handle)
at Internal.Cryptography.Pal.OpenSslX509CertificateReader.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert(ConfigurationReader configReader)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at myapp.Program.Main(String[] args) in /app/Program.cs:line 17
ステップ 4
準備した自己署名証明書を使って Docker コンテナでの起動確認。
Docker イメージはステップ3で docker build -t myapp_image .
して作ってあるはずなので以下。
% docker run --rm -it -p 5000:80 -p 5001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v ${HOME}/.aspnet/https:/https/ --name myapp myapp_image
ステップ 5
以下の様な docker-compose.yml を同一ディレクトリ上に作成し、起動確認。
version: '3.8'
services:
webapp:
build:
context: .
dockerfile: Dockerfile
ports:
- "5000:80"
- "5001:443"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password= { passward here }
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
volumes:
- ~/.aspnet/https:/https:ro
{ password here }
の部分を先ほど設定した自己署名証明書のパスワードに変更のこと。
% docker-compose up
できた。
ここから先他のミドルウェアを docker-compose.yml に足していく方法などは .NET Core に限った話ではないので割愛。
mcr.microsoft.com/dotnet/core/sdk:3.1-buster について
公式は
mcr.microsoft.com/dotnet/core/sdk:3.1
のイメージを使っているが
いかんせんイメージがデカすぎるのでこちらを使用した。
他にも alpine イメージである 3.1-alpine
などもあるので気になる人は
DockerHub をみにいってみて下さい。
- .NET Core By Microsoft - DockerHub
- .NET Core SDK - DockerHub
- ASP.NET Core 2.1/3.1 Runtime - DockerHub
参考:
- Adding MySQL to ASP.NET Core App With Docker Compose