Cant connect to docker container port of some images - docker

Trying investigate my issue with docker container. I lost a day when I thought that issue is in nodejs code (it has server and I am trying to connect to this server).
After investigations I found interesting thing for me.
For example - Lets run some test docker image:
docker run -p 888:888 -it ubuntu:16 /bin/bash
After that, prepare and install "simple server to listen our port":
apt-get update
apt-get install -y netcat
nc -l 888
After that I going to try to telnet localhost 888 from my system and got telnet: connect to address Connection refused. The same with nodejs image.
But if you try to use, for example, nginx container -
docker run -p 888:888 -it nginx /bin/bash
I will be successfull:
$telnet 888
Connected to localhost.
How it is possible, what I am missing? Why I can bind and use any port in nginx but not for other images?

When you run nc -l 888, you are creating a port that is listening explicitly for IPv4 connections. If we run ss -tln, we will see:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
When you run telnet localhost 888 on your host, there's a good chance it's trying to connect to the IPv6 localhost address, ::1. This connection fails if you're trying to connect an IPv4-only socket.
If you explicitly use the IPv4 loopback address by typing telnet 888, it should work as expected.
If you enable IPv6 support in nc by adding the -6 parameter:
nc -6 -l 8888
Then you get a socket that listen for both IPv4 and IPv6 connections:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 1 *:888 *:*
And if you attempt to connect to this socket using telnet localhost 888, it will work as expected (as will telnet 888).
Most programs (like nginx) open multi-protocol sockets by default, so this isn't normally an issue.


Cannot connect to Protonmail Bridge SMTP (host machine) from a Docker container

My setup is:
Debian, Docker
Host machine running Protonmail Bridge as a service
Docker container running Discourse with their default recommended setup
Issue: From the Docker container, I cannot connect to the SMTP server exposed by the Protonmail Bridge on the host machine.
I checked open ports on the host machine, all good:
ss -plnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096* users:(("proton-bridge",pid=953,fd=12))
How I test
Host machine:
openssl s_client -connect 127.0.01:1025 -starttls smtp
Docker container:
openssl s_client -connect -starttls smtp
Connection refused.
I’m wondering if the Protonmail Bridge service that’s listening on is not accepting connections from the Docker container because they are not coming from exactly? If this is the problem, how to validate and fix? If this is not the problem, what am I doing wrong?
Other tests
nmap on the host machine outputs:
Nmap scan report for localhost (
Host is up (0.000010s latency).
Not shown: 997 closed ports
22/tcp open ssh
1025/tcp open NFS-or-IIS
1042/tcp open afrog
Note that it lists the open port 1025.
nmap in the docker container does not output any 1025 port. I'm not sure if this is the problem either.
Output of route in the Docker container:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default UG 0 0 0 eth0 U 0 0 0 eth0
This may be impossible currently, but should be solved by this pull request.
If you're comfortable compiling the proton-bridge package from source, you only have to change 1 line in the internal/bridge/constants.go file to say
Host = ''
Host = ''
Then recompile with make build-nogui (to build the "headless" version).
And you should be good to go!

Port mapping problems with VScode OSS running inside a docker container

I would like to run the VSCode OSS Web Server within a Docker Container, as described here:
The Container is running, but the port mapping doesn't work. I run my image with
docker run -it -p 9888:9888 -p 5877:5877 vscode-server
but I got nothing with curl -I http://localhost:9888 on my machine. The VScode server is running, but the mapping to the host will not work. I think the problem is the binding. It looks like the VScode Server will bind to but should bind to
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0* LISTEN 870/node
tcp 0 0* LISTEN 881/node
Can anybody help here?

Why is it not possible to connect to my container from outside

I'm trying to execute a small Scala server in my computer, the code work well so the problem in my opinion is in the docker side.
Here you can see my Dockerfile:
FROM java:8-jdk-alpine
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
COPY ./target/scala-2.13/hello-world-assembly-1.0.jar /usr/app/
WORKDIR /usr/app
CMD ["java", "-jar", "hello-world-assembly-1.0.jar"]
Building command: docker build -t carloshn90/first-scala-server:latest .
Executing command: docker run -p 8080:8080 --name scala-server -it carloshn90/first-scala-server:latest
The problem is that when I try to execute a curl inside the container is working well:
docker exec scala-server curl localhost:8080 but not from outside.
Docker container status:
Curl inside the container:
Finally here the same curl but from outside the container:
My docker version is 19.03.08 and the operative system is macOS Catalina.
I would appreciate if someone have any idea about how to solve this problem
-------- Solution --------
Maybe this information is useful for others, in my case the issue was that the local address was localhost instead
/usr/app # netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:http-alt* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] STREAM CONNECTED 172119
When the correct local address should be
/usr/app # netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] STREAM CONNECTED 215241
Ensure that your app inside the container is listening on the external ip, and not only localhost ( This is typical done by listening on *:8080 or
Run this from outside the container:
curl -L http://localhost:8080

When to perform host-ip based port mapping like "-p host-ip:port:port"

Docker provides a way to map ports between the container and host.
As per the official documentation its also possible to mention host-ip while port mapping.
-p - Map TCP port 80 in the container to port 8080 on the Docker host for connections to host IP
I tried this option to figure out what's the difference with/without the host-ip.
Using just -p 80:80
$ docker run -itd -p 80:80 nginx:alpine
$ curl localhost:80
$ curl
$ curl
$ curl
$ ps -ef | grep docker-proxy
16723 root 0:00 /usr/local/bin/docker-proxy -proto tcp -host-ip -host-port 8080 -container-ip -container-port 80
All the curl commands return the output.
Using host-ip like -p
$ docker run -itd -p nginx:alpine
$ curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused
$ curl
curl: (7) Failed to connect to port 80: Connection refused
$ curl
curl: (7) Failed to connect to port 80: Connection refused
$ curl # return output
$ ps -ef | grep docker-proxy
4914 root 0:00 /usr/local/bin/docker-proxy -proto tcp -host-ip -host-port 80 -container-ip -container-port 80
All the curl commands failed except
Is there any there any other difference apart for the one I mentioned here.
Wondering when to use host-ip based port mapping. Any use cases?
A docker host may have multiple NICs. In the data center, this may be too segregate traffic, e.g. management, storage, and application/public. On your laptop, this may be for wireless and wired interfaces. There are also virtual NICs for things like loopback ( and VPN tunnels.
When you do not specify an IP in the port publish command, by default docker will bind to all interfaces on the host. In IPv4, this is commonly notated as which means listen on any interface (and this is why I don't connect to this address because there's no such thing as connecting to any IP). With the IP address specified, you manually specify which interface to use. Why would you want to specify this? Several reasons I can think of:
Listening on only to prevent external access
Listening on to explicitly bind to all IPv4 interfaces (it is possible to change docker's default behavior, so this could be necessary for some).
Listening on one physical NIC, allowing other NICs to be bound by other services on the same port.
Listening on only IPv4 interfaces if the app does not work for IPv6.
While there are lots of possible reasons, other than listening on loopback for security, these use cases are very rare and most users leave docker to listen on all interfaces.

Can connect to docker container when it runs apache, but not when it runs netcat on port 80

I am running a Debian server (stable), with the Debian package.This is the one distributed by Debian, not the one from the Docker developers. Since is only available in sid, I have installed from there (apt install -t unstable
My firewall does allow connections to/from docker containers:
$ sudo ufw status
Anywhere ALLOW ALLOW Anywhere
I also have this in /etc/ufw/before.rules :
So -- I have created an image with
$ sudo debootstrap stable ./stable-chroot > /dev/null
$ sudo tar -C stable-chroot -c . | docker import - debian-stable
Then started a container and installed apache2 and netcat. Port 1111 on the host machine will be redirected to port 80 on the container:
$ docker run -ti -p 1111:80 debian-stable bash
root#dc4996de9fe6:/# apt update
(... usual output from apt update ...)
root#dc4996de9fe6:/# apt install apache2 netcat
(... expected output, installation successful ...)
root#dc4996de9fe6:/# service apache2 start
root#dc4996de9fe6:/# service apache2 status
[ ok ] apache2 is running.
And from the host machine I can connect to the apache server:
$ curl
(... HTML from the Debian apache placeholder page ...)
$ telnet 1111
Connected to
Escape character is '^]'.
And it waits for me to type (if I type GET / I get the Debian apache placeholder page). Ok. And if I stop apache inside the container,
root#06da401a5724:/# service apache2 stop
[ ok ] Stopping Apache httpd web server: apache2.
root#06da401a5724:/# service apache2 status
[FAIL] apache2 is not running ... failed!
Then connections to port 1111 on the host will be rejected (as expected):
$ telnet 1111
Connected to
Escape character is '^]'.
Connection closed by foreign host.
Now, if I start netcat on the container, listening on port 80:
root#06da401a5724:/# nc -l 80
Then I cannot connect from the host!
$ telnet localhost 1111
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
The same happens if I try nc -l 80 in the container.
What could be happening? Both apache and netcat were listening on port 80. What have I missed?
I'd appreciate any hints...
update: if I try this:
root#12b8fd142e00:/# nc -vv -l -p 80
listening on [any] 80 ... inverse host lookup failed: Unknown host
invalid connection to [] from (UNKNOWN) [] 54876
Then it works!
Now it's weird... ifconfig inside the container tells me it has IP, but I can only use netcat binding to
root#12b8fd142e00:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet netmask broadcast
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
And Apache seems to want to instead:
2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using Set the 'ServerName' directive globally to suppress this message
but it actually uses
root#12b8fd142e00:/# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 12b8fd142e00:http TIME_WAIT
tcp 0 0 12b8fd142e00:39528 TIME_WAIT
Apache is not listening on, that's the address of the host (in the docker bridge).
In the netstat output, the local address has been resolved to 12b8fd142e00. Use the -n option with netstat to see unresolved (numeric) addresses (for example netstat -plnet to see listening sockets). is the foreign address that connected to Apache (an it's indeed the host).
The last line in the netstat output shows that some process made a connection to, probably to make an HTTP request. You can see the PID/name of the process with netstat -p.