I have a new ubuntu system and learning to use docker to serve web stuff, and I can ssh into from my laptop. how can I troubleshoot connecting docker to local network?
diagram:
[router]
|
+------------------+
| |
[laptop:macos] [server:ubuntu]
if I run on the server:
> docker run --rm -it -u root -p 80:80 strm/helloworld-http
then on the server run I can hit the docker server:
> curl localhost
<html><head><title>HTTP Hello World</title>...
but from my laptop via local network:
> curl http://172.*.*.*
<error cannot connect>
but if I run on the server a simple python script instead of docker:
> sudo python3 -m http.server 80
I can hit it from my laptop:
> curl http://172.*.*.*
<expected web page content success>
docker appears to be unable to connect to the network, or lacks permission to serve externally.
but it can successfully pull any data needed to build images
there are no firewalls setup on this machine yet
python servers can emit data over the same ip and ports, just not docker
solved on ubuntu by
sudo systemctl edit docker.service
and setting the ExecStart to have --ip=<machine ip>
Related
I have a Python application to expose a REST API. The Python server is running on http://127.0.0.1:5000
I have another application written in NodeJS to wrap the API coming from Python and expose another API as a passthrough. The Node server is running on http://localhost:8080
I'm new to Docker, I'm building a docker image for the Node application (in MacOS Silicon). The problem is when I invoke the API using curl http://localhost:8080 The docker desktop says "Connection refused: /127.0.0.1:5000"
The following is the docker run command I'm using
docker run --platform linux/amd64 -d -v ./Config.toml -p 8080:8080 myApp/app:v0.1.0
I tried with the --network host flag with the docker run command, but it doesn't work since it ignores all the declared ports. And I tried with the http.server --bind 0.0.0.0 with the docker run command, but the result says "pull access denied for http.server"
How can I solve this?
curl http://127.0.0.1:5000 on host machine to see if server is actually running.
Check server accessibility from within container. Simply run the docker container on interactive it and try access the server from the container.
docker run --platform linux/amd64 -it myApp/app:v0.1.0 /bin/bash
curl http://127.0.0.1:5000
If this does not work, it's a network configuration issue in the container you should set up to allow access to host machine.
If it works, then bind NodeJs app to 0.0.0.0 to allow conns from any ip.
docker run --platform linux/amd64 -d -v ./Config.toml -p 8080:8080 myApp/app:v0.1.0 -host 0.0.0.0
How to Connect to Host service on windows from within a Docker Container on Docker Desktop WINDOWS?
The service is running locally on localhost:9092
I tried using host.docker.internal but doesn't seems to work.
I tried this example from Docker-desktop document
https://docs.docker.com/desktop/windows/networking/#per-container-ip-addressing-is-not-possible
Run the following command to start a simple HTTP server on port 8000.
python -m http.server 8000
If you have installed Python 2.x, run python -m SimpleHTTPServer 8000.
Now, run a container, install curl, and try to connect to the host using the following commands:
docker run --rm -it alpine sh
apk add curl
curl http://host.docker.internal:8000
exit
The above doesn't seem to work on windows.
You should not start the service binded to localhost (127.0.0.1). Start the service binded to the IP of docker for desktop (192.168.x.x usually). Otherwise, start the service attached to all interfaces using 0.0.0.0, this could be insecure though.
Running docker for Mac 17.06.0 I have created a docker file that creates an image of Apache server. Notice it exposes port 80.
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y apache2
ADD index.html /var/www/html/
CMD /usr/sbin/apache2ctl -D FOREGROUND
EXPOSE 80
In the same folder of the Dockerfile I have created a simple index.httml file.
Then I built and ran it using
docker build -t webserver .
docker run -d webserver
I took the IP address of the running container using
docker inspect [container_name] | grep -i IPAddress
and when I curl
curl 172.17.0.2
I get no answer.
I do get an answer when running -p 80:80 and using localhost in the curl command.
curl localhost
But I want to understand why can't I curl the container IP.
Questions:
How can I get an answer for my curl?
I understand I can't ping my container when using docker for Mac (link).
Can I telnet it just to verify that the port is exposed?
Can I SSH it?
On Docker for Mac the Docker engine is running inside a small VM using Hyper-V. As consequence, the ip 172.17.0.2 is valid only inside that VM and not on your host system. See https://docs.docker.com/docker-for-mac/docker-toolbox/#the-docker-for-mac-environment for more details and comparison to other VM concepts like Docker Machine.
When you run your Docker container, you need to bind a local port to the container like so:
docker run -d -p 80:80 webserver
where the first 80 is the port on the localhost and the second is the port on the container that is exposed. Just having the port exposed in the dockerfile is not enough to access it from the localhost.
I'm having a problem, where I can't send network requests to a Docker container I've created. I've exposed the correct ports, so I'm not sure what other issues could be at fault here.
I have a server running in container alice at localhost:10009:
$ docker exec -it alice bash
bash-4.4# curl localhost:10009
curl: (52) Empty reply from server
Port 10009 is exposed from my container:
$ docker port alice
10009/tcp -> 0.0.0.0:10009
When doing the same curl from my host machine I get a different message:
$ curl localhost:10009
curl: (56) Recv failure: Connection reset by peer
I would check to see if the server application is configured to only listen to requests coming from its "localhost", this check depends on the type of server that you're using which is not mentioned.
an easy check is to start your container as follows:
docker run --network host -d yourimagename
You don't need to worry about port mapping since you're using the host network
then try to curl, if that works, then you'll just need to review your server listening IP setting.
curl localhost:10009
I think there are some problems with #Bouzid Zitouni's answer, according to Docker official documentation:
this is the same level of isolation as if the nginx process were running directly on the Docker host and not in a container
However, if you use the --network host you will not have isolated networking in the container, and the host networking driver only works on Linux hosts.
The problem of Connection refused/reset happens because your Server is listening on 127.0.0.1 inside the container and the port forwarding is going to external IP of the container (e.g. 172.17.0.2).
Solution
In your case you need to run a new container making your server to listen on all interfaces. Example using python http.server :
docker run -p 8000:8000 -it python:3.7-slim python3 -m http.server --bind 0.0.0.0
Note
The option --bind 0.0.0.0 it's specific option of http.server. Probally your server has other ways to specify this.
References:
https://pythonspeed.com/articles/docker-connection-refused/
https://docs.docker.com/network/network-tutorial-host/
I would like to expand on #Bouzid Zitouni's answer. It seems there is indeed an issue with the address(es) the server binds to.
Connection reset by peer usually indicates that one has defined a port mapping for the container that does not point to a listening server. Here is an example to illustrate this:
docker run -p 10009:10009 -it ubuntu bash
Install nmap in container:
apt-get update && apt install -y nmap
Run ncat (localhost only)
# ncat -v --listen localhost 10009
...
Ncat: Listening on 127.0.0.1:10009
Run curl on host:
# curl localhost:10009
curl: (56) Recv failure: Connection reset by peer
You actually get the same result even if you don't have any server process at all.
Run ncat (all IPs)
# ncat -v --listen 10009
...
Ncat: Listening on :::10009
Ncat: Listening on 0.0.0.0:10009
Curl on host connects successfully. Hope that helps.
I faced the same error with the docker container running locally on my machine/laptop.
I ran multiple containers and was using the same port number say 8080 for each container run.
After killing all docker process and restarting docker i am now able to connect to the container on the mentioned port 8080 in my case.
$ sudo service docker stop
Warning: Stopping docker.service, but it can still be activated by:
docker.socket
$ sudo service docker start
I’m experimenting with docker networking, and I can’t seem to find a way to accomplish the following:
Start a simple netcat server in the host:
nc -l -p 5555
and then communicate to this server from within a docker container, e.g.
# grab the docker network interface ip
hostip=$(ip route | awk '/docker0/ { print $NF }')
# pass in the docker network interface as a host and try a curl command
docker run --add-host=docker:"${hostip}" --rm -it hiromasaono/curl curl docker:5555
The curl request just hangs and the host netcat server does not receive a request.
If I instead start docker with --net=host option, it works:
docker run --net=host --rm -it hiromasaono/curl curl 127.0.0.1:5555
and the netcat server receives
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:5555
Accept: */*
How can I communicate to the simple host netcat server from within the docker container without using --net=host (the default is --net=bridge)?
(fyi: I'm running docker server/client 1.11.2)
Potentailly Relevant Resources I've Studied in search of an answer:
Document how to connect to docker host from container (github issue)
How to connect to Docker host from container (github issue)
Allow Docker Container to Connect to a Local Postgres DB
Docker Container Networking Documentation
As far as I understand, based on two comments[1][2], the following unofficial hack seems to be working for me as of today (2016.10.27):
In the Dockerfile for the app which needs to connect to the Docker host, I added the following lines:
...
# netstat
RUN apt-get update && apt-get install net-tools -y
...
CMD (netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2" dockerhost"}' >> /etc/hosts) && \
...old CMD line...
...
This seems to make the Docker host available to me from within the container as dockerhost.
Note to future readers: see also https://github.com/docker/docker/issues/23177 — as of writing, this issue is still open, so there's a non-zero chance it may become official at some point in future and supersede any workarounds; though it may also become closed and dismissed as happened to its various predecessors.
There are a couple of things you need to look into, in order to solve this problem.
Netcat must listen on all interfaces (or at least on the interface Docker clients can connect to). Not on localhost.
After you run netcat -l -p 5555 if in another terminal you run netstat -a -l -n | grep 5555 you should see 0.0.0.0:5555 or *:5555. If instead you see 127.0.0.1:5555 then it won't work and you need to fix this problem first before looking into Docker.
Docker must be able to ping the docker host and it must not resolve to 127.0.0.1 . Try docker run --net=host --rm -it hiromasaono/curl ping docker. If you see it's pinging 127.0.0.1 then your configuration is wrong and you need to fix this line: hostip=$(ip route | awk '/docker0/ { print $NF }') . If it's not 127.0.0.1 but the pings don't succeed then your network setup is wrong or the hostip is wrong.