3

I'm new to Docker and really want to experience its features. Here I would like to run a simple Asp.net core web api in Docker (using docker run) instead of running it using IIS.

It's simple because it's exactly the default auto-gen ASP.NET core Web API project with only one controller named ValuesController. Normally when debugging with IISExpress, the following URI should respond an array of values:

http://localhost:[some_port]/api/values

Now I add Docker support for the project (using Windows container). After building the Docker image, it can be listed using docker images. Now I run the Docker image to host my web api like this:

docker run -t -rm -p 80:50633 hellodocker:dev

It runs OK and I can check that using docker ps. However to test if it's actually working I've tried typing the following address into a browser:

http://localhost/api/values

and it's not working, nothing displayed and it looked just like a non-existent site.

When I try the following command docker exec [container_id] netstat, it sometimes shows a record with status of TIME_WAIT and almost the time there is not any. Although I'm not sure if this relates to the outside listening.

Here is the Dockerfile's content:

FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
WORKDIR /app
EXPOSE 50633
EXPOSE 44322

FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build
WORKDIR /src
COPY HelloDocker/HelloDocker.csproj HelloDocker/
RUN dotnet restore HelloDocker/HelloDocker.csproj
COPY . .
WORKDIR /src/HelloDocker
RUN dotnet build HelloDocker.csproj -c Release -o /app

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

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

I'm really stuck at this. A hello-world app may just print out a simple string but this hellodocker should be hosted in docker and serve any HTTP requests just like when we host it in IIS.

Update

After trying removing the built image and rebuilding another one instead, it looks like different after running with the same docker run command above:

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

As before nothing displayed and the prompt root path becomes C:\app. So this time it looks more obvious that it's listening for requests. However it's still not working.

2
  • What is the default port for the hello-world server? Are you sure that it is 50633? Commented Mar 14, 2019 at 1:03
  • @Jack Gore I'm not so sure, that's what I assumed based on the dockerfile, you can see the line EXPOSE 50633 Commented Mar 14, 2019 at 1:15

2 Answers 2

1

Before your ENTRYPOINT statement, try adding

 ENV ASPNETCORE_URLS=http://+:50633 DOTNET_RUNNING_IN_CONTAINER=true 

so it looks like this:

FROM base AS final WORKDIR /app COPY --from=publish /app . ENV ASPNETCORE_URLS=http://+:50633 DOTNET_RUNNING_IN_CONTAINER=true ENTRYPOINT ["dotnet", "HelloDocker.dll"]

Does that help?

Sign up to request clarification or add additional context in comments.

1 Comment

Actually I think we don't need that line (because it already exposes the web api via the default port 80, and we can just map that to the host's port 80 instead of mapping from 50633 to 80). The purpose here is to serve request from outside no matter port used inside. However your answer does force the listening (internally) on port 50633 which is not forced by the EXPOSE. With that line added, my original command works. Anyway thank you for this.
0

I am not sure why I could not search for a solution from Docker's forums but after trying searching for Now listening on: http://[::]:80 and it led me to an at-very-top link to a very similar issue in Docker's forums here.

So I've tried one solution there by using docker inspect [container_id] first to find the container's IP and used that IP to access the web API successfully :)

The container's IP can be found in the Networks section:

"Networks": {
            "nat": {
                "IPAMConfig": null,
                "Links": null,
                "Aliases": null,
                "NetworkID": "e336becc4500435f7338ebd8f84fef47ec2fc247f77bc82b6dbf49553f68afd5",
                "EndpointID": "a8ede68e3f4bb02392c295901f65d50f0ee014c114f564768d9c82a4644b0218",
                "Gateway": "172.30.240.1",
                "IPAddress": "172.30.242.85",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "00:15:5d:5a:29:8d",
                "DriverOpts": null
            }
        }

The correct address I used to test the web api now is:

http://172.30.242.85/api/values

UPDATE:

I assumed the EXPOSE 50633 means the docker will expose web api via port 50633 so I run the command docker run -t -p 80:50633 hellodocker:dev.

But actually the port it exposes here is still the default 80 (not sure why). But at least that makes sense. So to map the ports between docker and the host machine we use the command docker run -t -p:80:80 hellodocker:dev instead. I've tried that and it works perfectly for http://localhost/api/values.

I think the command used before docker run -t -p:80:50633 hellodocker:dev has useless ports mapping (at least for testing the web api from host machine), because the http://172.30.242.85/api/values should work if the docker actually runs the web api to listen on the default port 80.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.