ASP.NET Core + Docker not accessible on specified port

6.3k views Asked by At

It is impossible for me to access container with ASP.NET Core 3.1 application running inside. Goal is to run application in container on port 5000. When I'm running it locally using standard VS profile I navigate to http://localhost:5000/swagger/index.html in order to load swaggerUI. I would like to achieve same thing using docker.

Steps to reproduce my issue:

  • Add dockerfile with exposed 5000 port and ENV ASPNETCORE_URLS variable:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
    WORKDIR /app
    ENV ASPNETCORE_URLS=http://+:5000
    EXPOSE 5000
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
    WORKDIR /src
    COPY ["myapp/myapp.csproj", "myapp/"]
    RUN dotnet restore "myapp/myapp.csproj"
    COPY . .
    WORKDIR "/src/myapp/"
    RUN dotnet build "myapp.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "myapp.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "myapp.dll"]
    
  • Build image

     docker build -t myapp .
    
  • Run docker image:

     docker run myapp -p 5000:5000
    

Running commands above with specific docker file results in this:

    [21:28:42 INF] Starting host.
    [21:28:42 INF] Now listening on: http://[::]:5000
    [21:28:42 INF] Application started. Press Ctrl+C to shut down.
    [21:28:42 INF] Hosting environment: Production
    [21:28:42 INF] Content root path: /app

However, I can't access container using http://localhost:5000/swagger/index.html because of ERR_CONNECTION_REFUSED -> This site can't be reached.

I did get into container to check if host is running for sure, using:

docker exec -it containerId /bin/bash
cd /app
dotnet myapp.dll

what resulted in following error:

Unable to start Kestrel.
System.IO.IOException: Failed to bind to address http://[::]:5000: address already in use.

Conclusion is that port inside the container is used, application is alive, it's just not accessible from outside.I don't know how to get inside of it. Please point me into right direction.

UPDATE Issue is solved, answer is posted below. However explanation why it was needed and how it works would be nice!

3

There are 3 answers

0
Kalik On BEST ANSWER

To solve the issue I had to manually add "--server.urls" to entrypoint like shown below:

ENTRYPOINT ["dotnet", "myapp.dll", "--server.urls", "https://+:5000"]
0
Heisi On

Just two other hints, ENV variables are scoped in build-stages and will not be preserved. (It is not in your case).
Also the publish command in VS is set by default to Release and the initial program.cs has an

if ( app.Environment.IsDevelopment() ) 
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

clause. So swagger will not be available.

0
Sahitya On

I solved the same issue in the following way:

  1. Added the following in appsettings.json to force Kestrel to listen to port 80.
"Kestrel": {
  "EndPoints": {
    "Http": {
      "Url": "http://+:80"
    }
  }
}
  1. Exposed the port in dockerfile
ENV ASPNETCORE_URLS=http://+:80

EXPOSE 80

ENTRYPOINT ["dotnet", "EntryPoint.dll"]
  1. Ran the container using the below command.
docker run -p 8080:80 <image-name>:<tag>
  1. The app exposed on http://localhost:8080/