I'm running gunicorn inside a docker container. I know this works because sshing into it and curling localhost:8000/things in docker container gives me the response I want, however, I am not able to reach this on my host, despite docker telling me the port has been mapped. What gives?
I ran
docker run -d -p 80:8000 myapp:version1.1 /bin/bash -c 'gunicorn things:app'
docker ps gives me
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
614df1f2708e myapp:version1.1 "/bin/bash -c 'gunico" 6 minutes ago Up 6 minutes 5000/tcp, 0.0.0.0:80->8000/tcp evil_stallman
On my host, curling locahost/things gives me
curl: (52) Empty reply from server
However, when I docker exec -t -i 614df1f2708e /bin/bash and then curl localhost:8000/things, I succesfully get my correct response.
Why isn't docker mapping my port 8000 correctly?
When you publish a port, Docker will forward requests into the container, but the container needs to be listening for them. The container has an IP address from the Docker network, and your app needs to be listening on that address.
Check your gunicorn bind setting - if it's only listening on 127.0.0.1:8000 then it's not binding to the container's IP address, and won't get requests from outside. 0.0.0.0:8000 is safe as it will bind to all addresses.
Related
I start my docker container with:
docker run -it --expose 10001 --expose 8080 -p 10001:10001 -p 8080:8080 -p 80:80 --rm lucchi/covid90/100e
My docker -ps then has:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1521e0c3d947 lucchi/covid90/100e "/bin/sh -c /bin/bash" 2 seconds ago Up Less than a second 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:10001->10001/tcp funny_panini
But I can't connect to localhost from inside the container. I tried:
curl 0.0.0.0:8080
curl 127.0.0.1:8080
curl https://localhost:8080
but keep getting
curl: (7) Failed to connect to localhost port 8080: Connection refused
Most of the asnwers I read are about adding -p to the run command, I don't get what I'm missing.
Are you trying to connect inside the container?
If not, you may fight this other unrelated question (covering the outside container case) helpful:
From inside of a Docker container, how do I connect to the localhost of the machine?
Is the a server process running inside the docker on the specified port ?
If the app logs are enabled you can get the logs of the container by executing the below command.
docker logs <container_name>
Additionally for ensuring if the app is up and running fine, try doing a curl
from inside of the docker container. You can use the docker exec command to execute any command inside the container.
I have a container running HAProxy version 2.0 locally on Docker port 3001.
Config file is:
global
debug
defaults
log global
mode http
timeout connect 50000
timeout client 50000
timeout server 50000
frontend main
bind *:3000
default_backend app
backend app
balance leastconn
mode http
server dummy <localhostIP>:80
Docker file is:
FROM haproxy:2.0
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
Docker Run command:
docker run -p3001 --name my-running-haproxy my-haproxy
I am issuing a postman GET to port 3000 and expecting HaProxy to redirect to my server "dummy" on local port 80. But I am not able to get any legible response back. Appreciate any inputs.
If you run the the container like you did, Docker will assign a random port on your localhost and route traffic to port 3001. You can check which port that is by running docker ps after you started the container and looking at the PORTS section:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b502af649be my-haproxy "/docker-entrypoint.…" 1 minute ago Up 47 minutes 0.0.0.0:32769->3001/tcp upbeat_shtern
So on my example, you can access your application on port 32769, but this number is random.
Keep in mind, that in your example, Docker routes traffic to port 3001, whereas you configured your HAProxy to bind to port 3000. You would at least need to change the docker run command to the following:
docker run -p3000 --name my-running-haproxy my-haproxy
But usually you want to have a fixed port on localhost, e.g. port 80. Start your container like this to achieve that:
docker run -p 80:3000 --name my-running-haproxy my-haproxy
Now you can access your application at localhost:80.
I can curl localhost:5000 inside container but not from outside even when port binding added as 5000:5000
pramodjangam#Pramods-MacBook-Pro:~/code/helloworld$ curl localhost:5000/WeatherForecast
curl: (52) Empty reply from server
pramodjangam#Pramods-MacBook-Pro:~/code/helloworld$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f0c986867d9 kitematic/hello-world-nginx:latest "sh /start.sh" 10 minutes ago Up 10 minutes 0.0.0.0:32768->80/tcp hello-world-nginx
1200a6c8c7df helloworlddotnet "/bin/sh -c out/Hell…" 19 minutes ago Up 19 minutes 0.0.0.0:5000-5001->5000-5001/tcp great_haslett
pramodjangam#Pramods-MacBook-Pro:~/code/helloworld$ docker exec -it 1200a6c8c7df bash
root#1200a6c8c7df:/# curl localhost:5000
root#1200a6c8c7df:/# curl localhost:5000/WeatherForecast
[{"date":"2019-12-07T19:00:43.0919669+00:00","temperatureC":5,"temperatureF":40,"summary":"Balmy"},{"date":"2019-12-08T19:00:43.0920037+00:00","temperatureC":13,"temperatureF":55,"summary":"Cool"},{"date":"2019-12-09T19:00:43.0920128+00:00","temperatureC":52,"temperatureF":125,"summary":"Warm"},{"date":"2019-12-10T19:00:43.0920303+00:00","temperatureC":-3,"temperatureF":27,"summary":"Balmy"},{"date":"2019-12-11T19:00:43.0920383+00:00","temperatureC":46,"temperatureF":114,"summary":"Balmy"}]root#1200a6c8c7df:/#
root#1200a6c8c7df:/# exit
exit
I have ran into this sort of issues. Please make sure that your dotnet application running inside your docker container is also listening on all network interfaces.
For instance, whenever I run a Django application (in dev mode), I always make sure to see a message like this:
Starting development server at http://0.0.0.0:8000/
The key here is 0.0.0.0:8000 which indicates that my app, inside the container, is listening on all network interfaces.
Another option is to run your container with host networking mode (https://docs.docker.com/network/network-tutorial-host/)
I am having the same problem. It seems to be a dotnet 3.1 problem. When I start the app in the container it only binds to localhost:5000 and not to the other network interface. The problem is that localhost is always only reachable from the host (or in this case the container) itself, even if you port forward in docker it will not work.
I tried adding
.UseUrls("http://0.0.0.0:5000")
to the hostbuilder to make the app listen to all available network devices but it does not work, neither does adding:
ENV ASPNETCORE_URLS http://*:5000
This to the Dockerfile or
environment:
- ASPNETCORE_URLS=http://*:5000
to the docker-compose.
These options used to work fine in dotnet 2 but in 3.1 they do not have any effect. I also tried 0.0.0.0 instead of * nothing seems to work.
So basically dotnet always starts the Server on localhost (even on my developmachine) which makes your app only reachable from the host it is running on.
Inside the container, localhost refers to the container. Outside the container, localhost is your machine, not the container. When you want to access something running in the container outside the container, you need to use the container's IP address, not localhost.
You can get the container's IP address using:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_name_here]
I have a running Docker container which shows PORTS 9191/tcp. So on my browser, I tried accessing server using localhost:9191/api/.... However, browser throws an error This site can’t be reached
Here is a log to docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c214aefed15e shah "youtube-dl-server -…" 6 seconds ago Up 5 seconds 9191/tcp boring_swirles
This is what my docker file looks like
FROM mariozig/youtube-dl_server
RUN pip install --pre youtube_dl_server
EXPOSE 9191
ENTRYPOINT ["youtube-dl-server", "--host=0.0.0.0"]
You have not mapped the docker container port to host port.
The docker container runs on a host. And The host doesn't know which requests to be directed to the docker container. For that you have to to map the host port to docker container port using -p flag in docker run command as shown below:
docker run -d -p HOST_PORT:CONTAINER_PORT IMAGE_NAME
-p in this command will specify that you are forwarding your host port to the container port. In your local host in the port HOST_PORT will call the port CONTAINER_PORT of your container.
Now when you will access the HOST_IP:HOST_PORT then the host will redirect the request to corresponding container with which this HOST_PORT has been mapped.
For example I started a tomcat docker container and mapped the tomcat container's 8080 port to host's 9092 port by using the above command. When I do docker ps I can see the mapping under PORTS as 0.0.0.0:9092->8080/tcp
I'm unable to access a nodejs based service via http://localhost:8000 running in a docker image. I'm using Docker for Mac (https://docs.docker.com/docker-for-mac/)
I'm following the tutorial here https://nodejs.org/en/docs/guides/nodejs-docker-webapp/.
The server runs on port 8000. I start the docker image with the following:
$ docker run -p 8000:8000 -d geuis/node-server:latest
If I run docker ps I see:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fa2e446918b geuis/node-server:latest "npm start" 6 seconds ago Up 5 seconds 0.0.0.0:8000->8000/tcp unruffled_lewin
If I docker exec -it 9fa2e446918b /bin/bash I can access the docker vm and I can curl http://localhost:8000 and access the server from inside the container.
However, I try the same curl http://localhost:8000 from my system terminal and its not accessible.
Not sure what I need to do next.
Try the following listen statement:
app.listen(PORT, '0.0.0.0');
From reading the tutorial you mention it looks like express is listening on localhost. This is fine if you're running locally but inside of a container, localhost is not the same localhost that's outside of the container.
0.0.0.0 is the unspecified IPv4 address and so Express will bind on any IP it can find, which will be the IP that your requests are coming in from outside the container.