Steps to run local development of ASP.NET Core on Mac with docker-compose

This time I tried it with ASP.NET Core MVC, but it should be the same for the ASP.NET Core WebAPI project

TL;DR Just follow the steps in the Microsoft reference and you're good to go. Recommended to read in English. The Windows procedure is also well organized here.

Why i wrote

--Microsoft references were scattered all over the place and it was hard to grasp ――I was sad because I was stuck in the self-signed certificate part described later. --The repository you worked on this time is stored below (because it is a repository you are working on, things other than the article part may be added in the future) - https://github.com/JUNKI555/DotNETCoreIdentityPractice

Target environment, etc.

--Local environment (Mac) ――I don't think there is, but please prepare a certificate etc. when using it in a production environment etc.

Let's set up the procedure

If you try to do it all at once, you will be confused when you stumble, so it is important to do it in order

step 1

Create a new ASP.NET MVC application etc. and check the startup with dotnet run

% cd myapp
% dotnet new mvc -o .
% dotnet run

Step 2

Prepare the following Dockerfile and check the startup in the Docker container via HTTP connection.

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"]

The above Dockerfile is a sample when the Dockerfile is placed in the same layer as myapp.csprj. In the Microsoft reference, the sample has the following directory structure. (For .NET Core, the development method that divides the project and manages it collectively in the solution file is recommended? So the Microsoft sample is correct, but this time I wanted to do it in the same hierarchy)

After creating the Dockerfile, confirm the startup by HTTP connection with the following command

% docker build -t myapp_image .
% docker run -it --rm -p 5000:80 --name myapp myapp_image

Step 3

Prepare a self-signed certificate using the dotnet dev-certs command.

% dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p { password here }
% dotnet dev-certs https --trust

Set the {password here} part to each password.

Although it has nothing to do with the main line, I did not notice that I made a mistake in this setting ({passward hogefuga} etc. {}) When I started up using a self-signed certificate, I got the following error and did not start up.

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`1application,CancellationTokencancellationToken)
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`1application,CancellationTokencancellationToken)
   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

Step 4

Confirm the startup in the Docker container using the prepared self-signed certificate. The Docker image should have been created by docker build -t myapp_image . in step 3, so below.

% 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

Step 5

Create the following docker-compose.yml in the same directory and check the startup.

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

Change the {password here} part to the password of the self-signed certificate you set earlier.

% docker-compose up

did it. From here on, how to add other middleware to docker-compose.yml is not limited to .NET Core, so I will omit it.

About mcr.microsoft.com/dotnet/core/sdk:3.1-buster

The formula is I'm using the image mcr.microsoft.com/dotnet/core/sdk:3.1 I used this because the image is too big. There are other alpine images such as 3.1-alpine, so if you are interested, Take a look at DockerHub.

reference:

Recommended Posts

Steps to run local development of ASP.NET Core on Mac with docker-compose
Steps to run docker on Mac
Steps to build a Ruby on Rails development environment with Vagrant
Run Ubuntu + ROS with Docker on Mac
How to solve the local environment construction of Ruby on Rails (MAC)!
Run Edge (Chromium version) on Mac with Selenium
Steps to set up Jenkins on your local Mac, create one job and succeed
Build Java development environment with VS Code on Mac
How to run javafx with Raspberry Pi Posted on 2020/07/12
As of April 2018 How to get Java 8 on Mac
Run STS4 on Mac
Using multiple versions of Java with Brew on Mac + jEnv
A series of steps to create portfolio deliverables with Rails
A memo to build Jitsi Meet on Azure with docker-compose
Run the sample "Introduction to TensorFlow Development" on Jetson nano
Run batch with docker-compose with Java batch
Run TAO Core with Docker
Run chromium-mir-kiosk on Ubuntu Core
Results of trying to use NVENC (CUDA) with Ubuntu 18.04 on WSL2
[Core ML] Convert Cycle GAN to Core ML and run it on iOS
I tried to create a Spring MVC development environment on Mac
How to switch Java version with direnv in terminal on Mac
Steps to install Maven on Mac and use it in Eclipse