Docker Community Forums

Share and learn in the Docker community.

Web socket connection doesn't work inside Docker Container

I’m writing a Java app that needs to connect to a database backend. The connection is handled by the database SDK (Couchbase in this case), which starts up a replicator to a specific endpoint (wss://). When running this app from the IDE or by running the executable from the command line, everything works fine. However, when I build the Docker image, and then run the image in a container, the web socket connection fails to connect. From the log output, I can see that it gets stuck on “connecting”:

ReplicatorChange{replicator=Replicator{@450b4ee,<-,Database{@247240e5, name='<redacted>'},URLEndpoint{url=wss://<redacted>:443/data}], status=Status{activityLevel=CONNECTING, progress=Progress{completed=0, total=0}, error=null}}

Once the app reaches the above line, it gets stuck there and nothing happens. And it’s not a network issue, because HTTP connections work fine, since prior to this, the app creates a session by calling an HTTP endpoint.

I’m fairly new to Docker, so is there anything in the container that is preventing the replicator from connecting? I’ve looked into EXPOSE in the Docker file, and running with -p or -P, but none have worked so far.

When you specify a hostname or IP address​ to listen on (in this case localhost which resolves to 127.0.0.1), then your server will only listen on that IP address.

Listening on localhost isn’t a problem when you are outside of a Docker container. If your server only listens on 127.0.0.1:8000, then your client can easily connect to it since the connection is also made from 127.0.0.1.

When you run your server inside a Docker container, it’ll only listen on 127.0.0.1:8000 as before. The 127.0.0.1 is a local loopback address and it not accessible outside the container.

When you fire up the docker container with -p 8000:8000, it’ll forward traffic heading to 127.0.0.1:8000 to the container’s IP address, which in my case is 172.17.0.2.

The container gets an IP addresses within the docker0 network interface (which you can see with the ip addr ls command)

So, when your traffic gets forwarded to the container on 172.17.0.2:8000, there’s nothing listening there and the connection attempt fails.

The fix:
The problem is with the listen address:

server := http.Server{Addr: “localhost:8000”}
To fix your problem, change it to

server := http.Server{Addr: “:8000”}
That’ll make your server listen on all it container’s IP addresses.

Additional info:
When you expose ports in a Docker container, Docker will create iptables rules to do the actual forwarding. See this. You can view these rules with:

iptables -n -L
iptables -t nat -n -L

Thanks for the reply.

Just as a clarification, though, the app itself is not a server. It could be considered a “job” app – it does some work at the request of client apps, persists that work to the database, and then closes. In order to persist the work it does to the database, it establishes a connection to a wss:// endpoint that basically handles data transmission back-and-forth. It’s that connection that fails. The database SDK (Couchbase) never updates the status of the replicator once it attempts to connect, which suggests it’s stuck waiting on a response maybe?

The endpoint it connects to (wss://[redacted]:443/data) is controlled by us, so are you suggesting the change might need to occur there in order to listen for requests coming in?