6
3

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 3 years have passed since last update.

ASP.NET Core のMacでのローカル開発を docker-compose で動かすまでのステップ

Last updated at Posted at 2020-10-07

今回は ASP.NET Core MVC で試したが ASP.NET Core WebAPI プロジェクトでも同様のはず

TL;DR

Microsoft のリファレンスにあるステップどうりに進めればOK。英語で読むことを推奨。
Windowsの手順もこっちに十分まとまっています。

なぜ書いたのか

  • Microsoft のリファレンスがあちこちに飛び散っていて把握しづらかった
  • 後述する自己署名証明書の部分で詰まって悲しかった
  • 今回の作業したリポジトリは以下に格納してあります(作業中のリポジトリなので記事の部分以外のものが今後足されるかも)

対象環境など

  • ローカル環境(Mac)
    • 無いと思いますが本番環境などに利用する際は証明書など適宜準備して下さい
  • .NET Core 3.1
  • 想定ディレクトリ構成
    • myapp
      • Controllers
      • Models
      • Views
      • wwwroot
      • appsettings.Development.json
      • myapp.csproj
      • Program.cs
      • Startup.cs
      • Dockerfile
      • docker-compose.yml

手順立ててやっていこう

一気にやろうとするとつまづいた時に戸惑うので順序立ててやっていくのは大事

ステップ 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
  • 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 をみにいってみて下さい。

参考:

6
3
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?