Docker container fail to run ASP.NET Core app in SSL due to IApplicationBuilder.UsePathBase() error

I am having issues running a base ASP.NET Core web app in a Docker container. Here’s the Dockerfile:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build
WORKDIR /src
COPY ["PSN.Test/PSN.Test.csproj", "PSN.Test/"]
RUN dotnet restore "PSN.Test/PSN.Test.csproj"
COPY . .
WORKDIR "/src/PSN.Test"
RUN dotnet build "PSN.Test.csproj" -c Development -o /app/build

FROM build AS publish
RUN dotnet publish "PSN.Test.csproj" -c Development -o /app/publish

FROM base AS final
WORKDIR /app
EXPOSE 80
EXPOSE 443

COPY --from=publish /app/publish .
COPY PSN.Test.pfx /root/.aspnet/https/PSN.Test.pfx

ENTRYPOINT ["dotnet", "PSN.Test.dll"]

The Docker container image gets created just fine. If I run it with the following command I can reach the website at http://localhost just fine:

docker run -p 80:80 -p 443:443 -e ASPNETCORE_ENVIRONMENT=Development --name psn-test psn-test:latest

However, when I use the following command to run Kestrel with SSL enabled things break down:

docker run -p 80:80 -p 443:443 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_HTTPS_PORT=443 -e ASPNETCORE_URLS=http://localhost:80,https://localhost:443 -e ASPNETCORE_Kestrel__Certificates__Default__Password=test123 -e ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/PSN.Test.pfx --name psn-test psn-test:latest

Here’s the error message when I run it:

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 {67e83ec3-ba9b-4144-95ee-b26935280f1e} may be persisted to storage in unencrypted form.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to start Kestrel.
System.InvalidOperationException: A path base can only be configured using IApplicationBuilder.UsePathBase().
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.ParseAddress(String address, Boolean& https)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
Unhandled exception. System.InvalidOperationException: A path base can only be configured using IApplicationBuilder.UsePathBase().
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.ParseAddress(String address, Boolean& https)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   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 PSN.Test.Program.Main(String[] args) in /src/PSN.Test/Program.cs:line 16

The most notable error I can find is:

System.InvalidOperationException: A path base can only be configured using IApplicationBuilder.UsePathBase().

Based on what resources I can find, their resolutions point to either 1) update/correct launchSettings.json and/or 2) use app.UsePathBase() in the startup.cs file.

Here’s my launchSettings.json file:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:57851",
      "sslPort": 44345
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "PSN.Test": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

That looks right to me (and is it even used once it’s been published to a web server???).

Here’s my startup.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace PSN.Test
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UsePathBase(PathString.Empty);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Like I said, it’s standard fare except I added one line to the Configure() method to see if I can fix the issue:

app.UsePathBase(PathString.Empty);

What I am missing here? What else can I investigate to resolve this issue?

Source: Docker Questions