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.
Related
I'm trying to run httpd container
The ip address is 172.17.0.2 (I'm sure of it cause I've ran docker container inspect <container_name>) and I the port is 4400 and when I run the container can't access it via the browser on this address http://172.17.0.2:4400 !
I've tried to disable the firewall but still the same problem.
This is how I started it:
docker container run -d -p 4400:8080 httpd
This is what docker container ls give me
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9f92cfceb76 httpd "httpd-foreground" 24 minutes ago Up 13 minutes 80/tcp, 0.0.0.0:4400->8080/tcp interesting_wright
What am I missing ?
The problem was with wamp
when I disabled it I was able to access the container via http://localhost:4400
docker run -dit --name my-apache-app -p 4400:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
And then user your localhost + that port, and/or the LAN IP + that port.
Reference: https://hub.docker.com/_/httpd
I also was facing the same problem in windows with XAMPP installed
I resolved it by modifying the hosts file
/c/Windows/System32/drivers/etc
Just comment on the xampp IP and in this file you can also see the docker internal IP use it to access the application inside the container
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'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.
I am using boot2docker. I run one image at the daemon mode which starts grunt server at port 3000. This is the command I used to start it up.
That image has already exposed port 3000
docker run -d -P --name dummy image_name grunt server
docker ps
3af4ba19c539 image_name:latest "grunt server" 54 minutes ago Up 54 minutes 0.0.0.0:45000->3000/tcp dummy
and then run into the same container to "curl" the web server.
docker exec -it 3af4ba19c539 /bin/bash
curl localhost:3000
It gets the html.
However, when I try to connect it in my mac pc. It said "Connection refused."
curl $(boot2docker ip):45000
//curl: (7) Failed connect to 192.168.59.103:45000; Connection refused
I try to solve this problem by using VBoxManage, but it is not working either
VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port45000,tcp,,45000,,45000"
May I know how to solve this problem. Many thanks in advance
I need to see the source of your application to be sure, but I'm willing to bet you've bound to the local loopback interface (127.0.0.1 or localhost) in your application. If you instead bind to 0.0.0.0 to listen to all interfaces, you should find it is accessible from the outside.
I'm running under boot2docker 1.3.1.
I have a Docker container running a web server via uwsgi --http :8080.
If I attach to the container I can browse the web site using lynx http://127.0.0.1:8080 so I know the server is working.
I ran my container with:
$ docker run -itP --expose 8080 uwsgi_app:0.2
It has the following details:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5248ad86596d uwsgi_app:0.2 "bash" 11 minutes ago Up 11 minutes 0.0.0.0:49159->8080/tcp cocky_hypatia
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 5248ad86596d
172.17.0.107
I thought I could access that web site from my host by going to http://172.17.0.107:49159.
This does not work. I just see 'connecting...' in Chrome, getting nowhere.
What am I doing wrong?
Extending Anentropic's answer: boot2docker is the old app for Mac and Windows, docker-machine is the new one.
Firstly, list your machines:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
default * virtualbox Running tcp://192.168.99.100:2376
Then select one of the machines (the default one is called default) and:
$ docker-machine ip default
192.168.99.100
Ok, stupid me, I found the answer in the docs for boot2docker
https://docs.docker.com/installation/mac/#container-port-redirection
I needed to use the ip address of the boot2docker vm, rather than the ip of the container, i.e.
$ boot2docker ip
192.168.59.103
and I am able to browse my site from the host at http://192.168.59.103:49159/
I did not need to add any route on the host
To find the IP address of your container, you should need NO additional installs:
docker inspect <container>
This provides a wealth of info. grep it for the IPAddress.
You could use boot2docker port mapping option -L, as described here.
So, in your case it would be
boot2docker ssh -L 0.0.0.0:8080:localhost:8080
and then
docker run -it -p 8080:8080 uwsgi_app:0.2
That way, you do not have to use boot2docker's IP address: you can use localhost or your own IP address (and your docker container can be accessed from outside).
Boot2docker is outdated, but you may still have this problem on Docker for Windows or Mac, even though the same container works on Linux. One symptom is that trying to access a page on the server inside the container gives the error "didn't send any data" as opposed to "could not connect."
If so, it may be because on Win/Mac the container host has its own IP, it's not localhost as it is on linux. Try running Django on IP 0.0.0.0, meaning accept connections from all IPs, like this:
python manage.py runserver 0.0.0.0:8000
Alternatively, if you need to make sure the server only responds to local requests (such as from your local proxy like nginx, apache, or gunicorn) you can use the host IP returned by hostname -i.
And make sure you are using the -p port forwarding option correctly in the docker run command.
Assuming all is well, you should be able to access your server at http://localhost in a browser running on the host machine.
docker build -t {imagename} .
docker build -t api-rest-test .
docker run -dp {localport}:{exposeport} image:name
docker run -dp 8080:8080 api-rest-test:latest
make sure you are using the same port for yourlocalport and exposeport
then you can access your rest service in your local machine http://localhost:8080
[EDIT: original version was ignoring the -P in question]
If you want to get to the containers without having to 'publish' the port (which changes its number)
there is a good run-through here.
The key is this line:
sudo route -n add 172.17.0.0/16 172.16.0.11
which tells the Mac how to route to the private network inside the VirtualBox VM that the Docker containers are on.
Had the same issue and in my case i was using AWS EC2 instance. I was trying with the container IP which did not work. Then I used the actual public IP of the AWS host as the IP, which worked.
How to troubleshoot the issue on hosting application on local host browser
For this launch the container with below command, in my case it was:
[root#centoslab3 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b81d8a0e3e1 centos:baseweb "/bin/bash" 8 minutes ago Exited (0) 24 seconds ago webtest
[root#centoslab3 ~]# docker run --name=atul -v /root/dockertest:/var/www/html -i -t -p 5000:8000 centos:baseweb /bin/bash
In the httpd configuration:
[root#adb28b08c9ed /]# cd /etc/httpd/conf
[root#adb28b08c9ed conf]# ll
total 52
-rw-r--r--. 1 root root 34419 Sep 19 15:16 httpd.conf
edit the file with the port 8000 in listner and update the container ip and port under Servername.
Restart the httpd service and you are done.
Hope this helps