1
votes

Im new to Docker and im trying to set up 2 containers, one running mongoDB and one running the web application.

The problem is that I can not access my .NET core application via localhost:5000 or 0.0.0.0:5000.

Mongo is running fine.

Here is my docker-compose.yml

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  mongo:
    build: ../../../docker/wishare-mongo/
    volumes:
     - ../../../docker/wishare-mongo:/data/db
    ports:
     - "27017:27017"

Dockerfile for .NET Core app

FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
ENV ASPNETCORE_URLS="http://*:5000"

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
EXPOSE 5000
ENTRYPOINT ["dotnet", "Wishare-Integration-Api.dll"]

The docker-compose build and docker-compose up runs without an error with this resulting for web container:

web_1 | Hosting environment: Production web_1 | Content root path: /app web_1 | Now listening on: http://[::]:80 web_1 | Application started. Press Ctrl+C to shut down.

And this is the result of docker ps, port 5000 should be exported based on docker ps result.

Docker ps result

Any ideas?

2
The output indicates the app is listening on port 80 inside the container. Do you have something in your app startup that explicitly sets the port to 80? That may be overriding the environment variable.nlawalker
Also, on the host, try explicitly using 127.0.0.1 instead of localhost. I've seen some environments configured where localhost doesn't work.nlawalker
To answer your questions, @nlawalker no I did not change anything, when running the app directly trought VS instead of docker it loads at port 5000. Also, 127.0.0.1 does not work neither, not on port 5000, nor 80Michal Takáč

2 Answers

2
votes

Looks like .NET uses port 80 in production, so when Ive changed docker file and exported port 80 instead of 5000 and also changed port 5000 to port 80 in docker-compose it works as supposed.

So I assume in order to run it on port 5000 it will need some configuration on .NET side.

2
votes

Problem & Solution Summary:
By default, ASP.NET Core only listens to localhost, instead of any IP addresses, usually this is configured in code level or appSettings.json or launchSettings.json: http://localhost:5000. You can easily change this to "http://*:5000" to solve the problem. (You can specify the IPs which you want the app to listen to)

Verification:

Works in container with localhost:

We can get into container bash,

docker exec -ti <container name> /bin/bash

Verify by running

curl -X GET http://localhost:5000

Doesn't work in container with IP

curl -X GET http://{thecontainer IP}:5000

Doesn't work in the local machine with localhost

In docker compose, even mapped 5000:5000. But it doesn't work when access http://localhost:5000 on local pc

Doesn't work in the local machine with IP

  1. use ipconfig to get your local ip. i.e. 192.168.1.123
  2. run your asp.net core app
  3. access your app within browser by using IP instead of localhost: http://19.2.168.1.123 You will see it won't work.

Why, Here is how the browser routes to the App in docker container?

  1. your localhost (type in browser) -> your local IP 192.168.1.123
  2. your local IP 192.168.1.123 -> Container IP: 192.168.4.45 (per your docker desktop setting)
  3. Container IP: 192.168.4.45 -> Container localhost
  4. Container localhost -> the App running Container.

If the app only listens localhost, then,

Step 4: works.

Step 3 won't work,

Step 2 and Step 1 won't work.

So, the solution is to change the application to make sure it listens to both localhost & the desired IPs.

Here is one example (ASP.NET Core 3.1) how to solve the problem. Definitely, you can put these URLs into appSettings, or other configurations.

        internal static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    // In order to use Docker Container, we need to use *:5000
                    // to listen all IPs instead of only localhost.
                    // feel free to move these IPs settings into appSettings.json
                    webBuilder.UseUrls("http://*:5000","https://*:5001");
                })
                .UseAutofac()
                .UseSerilog();

Note: How to get container IP

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id

ServerUrls explaination from MSDN

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0#server-urls (Instead of hardcode in configuration, you can use environment variable ASPNETCORE_URLS, too)