'Docker - can not expose on port 80

I have a problem with expose my .Net Core App on Docker.

My Dockerfile starts like that

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

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build
WORKDIR /src

I build it and run:

docker run -d -p 8080:80 --name test testapp

Container starts but I can not access the app on port 8080

In the container logs I can see that

warn: Microsoft.AspNetCore.Server.Kestrel[0]

Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'.

info: Microsoft.Hosting.Lifetime[0]

Now listening on: http://localhost:5000

but I was expecting:

Now listening on: http://[::]:80

Why can not understand why this is not 80 and I can not reach my app from outside, even if run it with 8080:5000

CURL to loclalhost:5000 from inside the container returns proper HTML



Solution 1:[1]

The application runs on port 5000 and you are trying expose 80. So change your Dockerfile and expose 5000

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

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build
WORKDIR /src

Now run the image by exposing 5000 port

docker run -d -p 8080:5000 --name test testapp

Solution 2:[2]

You can use the ASPNETCORE_URLS environment variable to tell Kestrel to listen on a host/port different from localhost:5000.

I.e.

docker run -d -p 8080:80 -e ASPNETCORE_URLS=http://+:80 --name test testapp

More info on that in the docs.

Now, in my experience, I need to set this environment variable if I have my entrypoint/cmd to do dotnet run. On the other hand, if I set it to use the DLL, i.e. CMD ["dotnet", "testapp.dll"], it listens on 0.0.0.0:80 by default, meaning I do not have to set the ASPNETCORE_URLS variable.

So you could also play a bit with your entrypoint/cmd. I couldn't find this part documented, so unsure exactly how it works...

Solution 3:[3]

Which operating system are you using? I had the exact same issue using Fedora. If you are using Fedora or RHEL, Docker networking requires additional configuration to work.

See https://fedoramagazine.org/docker-and-fedora-32/

(I do not have sufficient reputation to comment so I am answering).

Solution 4:[4]

We had this same issue and could not find a resolution to this problem. This occurred for us in a .net 6 application and took us days to troubleshoot.

The environment for us was: a c# REST API docker composed up in a debian container launched on a windows operating system.

The ports are opening correctly most likely on your container and you look to be mapping your local port to the container port correctly. So most likely all of that is correct.

However it is likely the application itself is not running on port 80 inside the container. Kestrel runs on port 5000 by default which is why you are seeing the 5000 error.

If you are running .net 5 or 6 you can add this to program.cs

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(80);
}
);

To tell kestrel to listen on port 80 on both the ipv4 and ipv6 interfaces.

For us this instantly forced the app to run on port 80 inside the container.

To confirm this is the issue you can always use docker desktop and go inside your linux container (command line interface) and see what is running on the ports in the linux container. To do this you can use netstat - a but you need to install net-tools first (most likely).

In the linux container

apt update
apt install net-tools  

netstat -a

If kestrel is running on port 80 you will see port 80 exposed. if it is running on port 5000 you will see it running on port 5000.

For us we were running on port 5000 before we made the adjustment. After the adjustment we were running on 80 appropriately and were instantly fixed.

port 5000 in linux container enter image description here

port 80 in linux container

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Punker
Solution 2 Christian Fosli
Solution 3 Daniel Levin
Solution 4 Matt