17

I have a Docker container running on my Ubuntu Linux 14.04 machine that exposes a port publicly:

docker run --name spacyapi -d -p 127.0.0.1:7091:7091 jgontrum/spacyapi:en

I can connect and execute commands against the server in the container without problem from the local machine. For example:

curl http://localhost:7091/api --header 'content-type: application/json' --data '{"text": "This is a test."}' -X POST

The command executes faithfully. However, if I try the same CURL command from an external machine I get a "connection refused" error:

curl http://192.5.169.50:5000/api --header 'content-type: application/json' --data '{"text": "This is a test."}' -X POST
curl: (7) Failed to connect to 192.5.169.50 port 7091: Connection refused

Where 192.5.169.50 is the IP address of the box running the Docker container.

I don't think I need any iptables rules because I didn't need to set any up for the Node.JS server running on the same box. All the other computers on my local network can access the Node.JS server just fine. But not the Docker container acting as a server.

How can I fix this?

Robert Oschler
  • 14,153
  • 18
  • 94
  • 227
  • I don't think the container's IP is 192.5.169.50. Try doing `docker inspect | grep IPAddress` to check what the IP of the container is. – Bill Cheng Apr 06 '17 at 02:12
  • @BillCheng - 192.5.169.50 is the IP address of the box running the Docker spaCy container. I am accessing that box from another box on our Intranet. – Robert Oschler Apr 06 '17 at 12:16
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. Also see [Where do I post questions about Dev Ops?](http://meta.stackexchange.com/q/134306) – jww Apr 07 '17 at 09:54

2 Answers2

15

You didn't publicly publish your port with this flag:

-p 127.0.0.1:7091:7091

That flag says to publish on the host 127.0.0.1 interface (localhost), port 7091 to the containers port 7091. The only way to reach that port is to be on the host and connect to the loopback interface.

To publicly publish the port, remove the IP from that flag:

-p 7091:7091

or explicitly publish to all interfaces with:

-p 0.0.0.0:7091:7091

The latter format is identical to the first one as long as you haven't overridden your docker daemon settings with dockerd --ip x.x.x.x or setting the ip value in your /etc/docker/daemon.json file.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Thanks! I used the first example you show and now it works.. Can you add to your answer what the effective/actual difference is between using or not using 0.0.0.0 as part of the port assignment command line argument, especially if there are any differences in security or availability between the two formats? – Robert Oschler Apr 06 '17 at 12:14
  • 1
    Docker defaults to using 0.0.0.0 unless you override it with a setting to the `dockerd` daemon, so the two formats are normally identical. – BMitch Apr 06 '17 at 12:20
6

I don't think the container's IP is 192.5.169.50. Try doing docker inspect <container-uid> | grep IPAddress to check what the IP of the container is. I believe it should be something like 172.17.0.X.

Also you could just do docker run -d --network=host <image> which stacks the container on top of the host network.

Container are just something on top of the host, the host is the one that is actually communicating with the outside.

Bill Cheng
  • 732
  • 1
  • 8
  • 15