Cannot access url on my dockerized web app endpoint - docker

I have started my .net core 3.1 web app under docker container and I'm having info from docker desktop client
Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app
My controller looks like this
[Route("hello/[controller]")]
public class WorldController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok();
}
}
since my container is running on port 80 I'm trying to access controller action using
http://localhost/hello/world
but I'm getting HTTP Error 404.0 - Not Found
Am I missing something? Any suggestions?
Update:
Dockerfile
...
ENV ASPNETCORE_URLS http://*:57362
EXPOSE 57362
Even though I'm explicitly exposing 57362 docker still gives the message Now listening on: http://[::]:80

You can change the port ASPNETCORE will listen with the following directive in the Dockerfile:
ENV ASPNETCORE_URLS=http://+:80;https://+:443
If you want to change the default HTTP port to be 57362 you should do:
ENV ASPNETCORE_URLS=http://+:57362
After building the docker image, the application will run under port 57362 inside the container. To forward any port of your computer to the container port you need to run the container with the -p parameter as follows:
docker run -tid -p <host_port>:<container_port> my_image:<my_tag>
In your case it should be the following:
docker run -tid -p 80:57362 my_image:<my_tag>
If you're running this script on Windows on Docker for Desktop, it will only allow the binding of port 80 from an elevated prompt. If not running on an elevated prompt you can change it to port 8080 or any other.

You will need to map port 80 to 57362. This would look something like this inside a docker-compose.yml file if you have a docker-compose file thats to say and using the docker-compose up -build command
ports:
80:57362

Related

Docker: Connect to Wildfly server from outside

I am having trouble connecting to a Wildfly server running in a Docker Desktop container. My Dockerfile is like so:
FROM jboss/wildfly:9.0.1.Final
COPY ./standalone-template.xml /opt/jboss/wildfly/standalone/configuration/standalone.xml
COPY ./MyApplication.war /opt/jboss/wildfly/standalone/deployments/MyApplication.war
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
The server seems to start successfully, and at the end of the output from the CMD running docker run -it mydockerimage I see this output:
19:20:21,260 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 62) WFLYUT0021: Registered web context: /MyApplication
19:20:21,338 INFO [org.jboss.as.server] (ServerService Thread Pool -- 34) WFLYSRV0010: Deployed "MyApplication.war" (runtime-name : "MyApplication.war")
19:20:21,568 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0061: Http management interface listening on https://0.0.0.0:9993/management
19:20:21,569 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0052: Admin console listening on https://0.0.0.0:9993
However, I am not able to connect to the server's admin console or the application from my machine's browser, I get ERR_CONNECTION_REFUSED. When I modify the docker run command to be docker run -it -p 9993:9993 mydockerimage I am able to connect to the admin console, but I can't do the same for the application itself. Normally for an https Wildfly server I wouldn't use any port when trying to connect through the browser, but trying to do https://localhost/MyApplication fails.
What should I change to allow connection to the "MyApplication" web context?
You need to include port 8080 in run command
docker run -it -p 8080:8080 -p 9993:9993 mydockerimage
and access your application at not https://localhost/MyApplication but at https://localhost:8080/MyApplication, or any other port that you choose in -p 8080:8080 for host port.

From inside of a Docker container, how do I connect to another process listening inside the same container?

I have spent a couple of hours researching this and the consensus seems to be that using host.docker.internal instead of localhost should allow one process within a container to connect to another process within the same container.
However, host.docker.internal does not work for me.
Environment:
Docker Desktop 4.6.1 running on Windows 10
docker run command running on WSL2 Ubuntu
Command:
docker run -p 80:80
Error
Connection timeout
Dockerfile contents
FROM openjdk:17-alpine
COPY xxx/target/AAA.jar AAA.jar
COPY xxx/target/BBB.jar BBB.jar
COPY xxx/target/CCC.jar CCC.jar
COPY ./dockerboot.sh dockerboot.sh
ENTRYPOINT ["sh", "-c", "./dockerboot.sh"]
EXPOSE 80
dockerboot.sh contents
java -jar AAA.jar &
java -jar BBB.jar &
java -jar CCC.jar &
wait
The AAA, BBB, CCC jars contain java Springboot applications listening on ports 80, 8081, and 8082 respectively.
The answer is to just use localhost or 127.0.0.1.
It turns out the root cause of my issue was unrelated to Docker networking:
One of the microservice jars was malformed (no main manifest attribute) and was not starting up correctly, hence, failing to listen on port 8081 and causing Connection refused.

expose docker container's application url to host

I have a docker image with some ruby on rails environment built in (i.e. installing some rails gems and system packages) and I have an EXPOSE 3000 to expose the port at the end.
I ran a container with docker run -p 3000:3000 -ti <image> bash, then start the rails server. The logs are saying the web server is available on localhost:3000. I tried to connect to both the IPAddress as specified in docker inspect <id> and localhost on my host machine, but neither would be able to connect. What could be the problem here?
If your application is listening on localhost, it will only respond to requests from the container's localhost - that is, other processes inside the container.
To fix this you need to set the listen address of your server to listen to any address (usually, you specify this as 0.0.0.0). I've never used rails, but from a quick search, you should use the -b option.
So changing your ENTRYPOINT or CMD in your Dockerfile to contain -b 0.0.0.0 would probably do it.

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
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...
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
port 80 in linux container
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
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).

Unable to run application on Docker if used any other port except default port 80

I have a demo app which is hosted on docker. The exposed port for Docker is 80 and the app is running fine on local machine and I am able to see landing page for my app on localhost:8888.
Docker file is as given below
FROM microsoft/aspnetcore:2.0
COPY dist /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "demoapp.dll"]
Whenever I change line "EXPOSE 80/tcp" to for ex- "EXPOSE 8080/tcp" , "EXPOSE 5000/tcp" etc to expose any other port except 80 of Docker container as given in many online available sample codes, I am unable to run my app on browser. Any port except 80 is not working.
I am able to create image and create container for application too. Everything goes well but when I try to run app on browser (localhost:8080/5000/9000 etc.) The app landing page doesn't load.
Any suggestions? Do I need to do some port related configuration or contact my network team? or any code which I am missing here?
You should be able to expose any port inside the container.
However you publish the exposed port on the host during the start of the container.
This is done with the -p flag of the docker run command.
When you say you are able to access the application using localhost:8888 it means you have run the docker run command with -p 8888:80. This publishes the container port 80 onto the host as port 8888.
To use any other port just change the docker run command to -p 8888:<new exposed port> and that should do it.
See the docker run command help for more info:
https://docs.docker.com/v17.12/edge/engine/reference/commandline/run/#publish-or-expose-port--p-expose
Publish or expose port (-p, –expose)
$ docker run -p 127.0.0.1:80:8080 ubuntu bash
This binds port 8080 of the container to port 80 on
127.0.0.1 of the host machine. The Docker User Guide explains in detail how to manipulate ports in Docker.
If your application runs at port suppose 8080 then make sure to do port mapping while running the container.
docker run -itd -p 8080:8080 <image>
This will map port 8080 of host on port 8080 inside the container. (-p hostport:containerport)
If you don't want port mapping then run docker container in host mode.
docker run -itd --net=host <image>
In this case your container use host network, so whatever port your application is running inside it should get exposed.
For microsoft/aspnetcore, it sets the ASPNETCORE_URLS environment variable to http://+:80 which means that if you have not explicity set a URL in your application, via app.UseUrl in your Program.cs for example, then your application will be listening on port 80 inside the container.
Reference: microsoft/aspnetcore
If you want to change the default port 80, you need to use UseUrls in Program.cs with like below, and use EXPOSE 8080/tcp in dockerfile.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://+:8080")
.UseStartup<Startup>();
Or, you need to change ASPNETCORE_URLS environment like
FROM microsoft/aspnetcore:2.0
COPY dist /app
WORKDIR /app
EXPOSE 8080/tcp
ENV ASPNETCORE_URLS=http://+:8080
ENTRYPOINT ["dotnet", "demoapp.dll"]
Command to run
docker run -it -p 8080:8080 mytest

Resources