ASP.NET Core Docker Container App not accessible

Viewed 11915

I run an ASP.NET Core service in a Docker container on MacOS.
Visual Studio for Mac v18.1.2 (build 2) .NET Core SDK: 2.2.300

Here is the Dockerfile:

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

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /
COPY src/Services/Service.API/Service.API.csproj src/Services/Service.API/
RUN dotnet restore src/Services/Service.API/Service.API.csproj
COPY . .
WORKDIR /src/Services/Service.API
RUN dotnet build Service.API.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish Service.API.csproj -c Release -o /app

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

Here is how the docker-compose file for the service looks like:

service.api:
  build:
    context: .
    dockerfile: src/Services/Service.API/Dockerfile
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=http://+:80;https://+:443
    - ASPNETCORE_HTTPS_PORT=5254 
    - ASPNETCORE_Kestrel__Certificates__Default__Password=crypticpassword
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
  ports:
    - "5204:80"
    - "5254:443"
  volumes:
    - ${HOME}/.aspnet/https:/https/

The ports of the running Docker container looks good too:

0.0.0.0:5204->80/tcp, 0.0.0.0:5254->443/tcp

But when I try to call https://localhost:5254 it says site cannot be reached.

Also in the output I see following warning:

warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to https://localhost:5001 on the IPv6 loopback interface: 'Cannot assign requested address'. Microsoft.AspNetCore.Server.Kestrel:Warning: Unable to bind to https://localhost:5001 on the IPv6 loopback interface: 'Cannot assign requested address'. Hosting environment: Development Content root path: /app Now listening on: https://localhost:5001

Why doesn't it take the urls set by the ASPNETCORE_URLS enivronment variable?

What else could I do for troubleshooting to find the problem?

5 Answers

I had your problem a while ago, this is how I fixed it. You need to specify --server.urls as a running argument like below:

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Service.API.dll", "--server.urls", "http://+:80;https://+:443"]

And where that 5000 and 5001 come from?

Kestrel Endpoint configuration

By default, ASP.NET Core binds to:

http://localhost:5000

https://localhost:5001 (when a local development certificate is present)

Update 1:

According to your docker-compose configuration, you have set ASPNETCORE_ENVIRONMENT to Development. I think you should change it to Production because when you enable Development the ASP.NET Core will read settings from launchSettings.json.

The development environment can enable features that shouldn't be exposed in production. For example, the ASP.NET Core templates enable the Developer Exception Page in the development environment.

The environment for local machine development can be set in the Properties\launchSettings.json file of the project. Environment values set in launchSettings.json override values set in the system environment.

As far as I remember the default ports for Kestrel are 80 and 443 in every default launchSettings.json.

If you need to run your project in development mode on Docker you should change configuration inside launchSettings.json but I think it's not recommended and it's better to change the mode to Production.

service.api:
  build:
    context: .
    dockerfile: src/Services/Service.API/Dockerfile
  environment:
    - ASPNETCORE_ENVIRONMENT=Production
    - ASPNETCORE_URLS=http://+:80;https://+:443
    - ASPNETCORE_HTTPS_PORT=5254 
    - ASPNETCORE_Kestrel__Certificates__Default__Password=crypticpassword
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
  ports:
    - "5204:80"
    - "5254:443"
  volumes:
    - ${HOME}/.aspnet/https:/https/

First, check if your container is up and running with:

docker ps

If it is running, Kestrel inside the container may not be started. You may need to check your entrypoint, Linux in the container is case sensitive. In this case, try to run your app manually. First, get into the container by:

docker exec -it your_container /bin/bash

cd /app

dotnet yourprojectfile.dll

and then navigate:

https://localhost:5254

Basically, in the asp.net core code, it only listens to localhost which is in Container, but not your local pc. You can solve the issue by updating your setting to listen "http://*:5000" instead of "http://localhost:5000".

Here is a detailed explaination of the cause and solution. https://stackoverflow.com/a/65953771/8918445

For your current docker-compose.yml, you are referring the existing image service.api:${TAG:-latest} directly instead of using the generated image from the dockerfile.

Remove this line image: service.api:${TAG:-latest}

version: '3'
services:
  service.api:
  build:
    context: .
    dockerfile: src/Services/Service.API/Dockerfile
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=http://+:80;https://+:443
    - ASPNETCORE_HTTPS_PORT=5254 
    - ASPNETCORE_Kestrel__Certificates__Default__Password=crypticpassword
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
  ports:
    - "5204:80"
    - "5254:443"
  volumes:
    - ${HOME}/.aspnet/https:/https/

Turns out this is a bug in Visual Studio for Mac v18.1.2 (docker-compose up works)

Related