Trouble with networking in 1 direction

I have 2 apps, client and server, I’ve dockerized the server and it runs in docker correctly, it receives packets sent from outside the container to a udp port 12000 it listens on, but it cannot reply (send a response packet) back to the client outside the container.

Inside the container the server listens on udp port 0.0.0.0:12000, all packets sent to it arrive correctly and it processes them

The game client is listening on 0.0.0.0:11000 on the machine docker is running. I get that docker is a VM and isolated.

When it receives a packet, it saves the endpoint of the sender, and sends a reply packet.

On the same computer on localhost the game client is listening on a udp 11000 port. The server addresses clients by their ipaddress:port, example it’s saying my client endpoint is 172.18.0.1:11000, but any packets it sends to that ip:port don’t get out of the container.

When testing outside docker, both apps work together perfectly, but when I run it from docker, only inbound messages work not outbound.

I’ve scoured stackexchange, discord, still stuck.

My docker compose file is basic, the thing is it runs just the outbound networking is broken:

version: '3.4'
services:
    app:
        build:
            context: .
            dockerfile: Dockerfile
        ports:
            - 12000:12000/udp
            - 11000:11000/udp

Any way to narrow down why outbound doesn’t work while inbound does?

The first part is incorrect: docker is a container engine. A container is just an isolated process on the host kernel.

It is not intended to access a container by its ip. For host/lan to contaienr communication, ports need be published on the host and then be accessed by the host-ip and published host port.

Your compose file already publishes the port to the host, so it is impossible that another process on the host can bind the same port again. If your client application allows modifying on which port the server can be reached, you could try to change how you publish the ports, in order to avoid port collision.

I’ve tried removing the 11000 port (outbound) and I’ve tried using a different port on both apps. Say I just use 12000 to send/receive, when it sends it instantly receives on the same port… doesn’t get to the opposing app.

If the game client on the host computer is listening on ipaddress any, port 11000. Should I not be opening 11000 on the docker container? Docker container receives on 0.0.0.0:12000 and prints the sender ip as 172.18.0.1, it then tries to send to 172.18.0.1:11000 and that doesn’t get out of the container

First I thought I am not able to follow your thought… but then it made click: containers in a bridge network only see the gateway ip of that bridged network. Your problem is that the source ip is not retained.

It is only retained if you use the host network, macvlan or ipvlan.

It works without problems for request/response communication, but does not work if you depend on the source ip to initiate a new request from the container to the source ip.

1 Like

Thanks it wasn’t clear at all in any docs I read, that’s gotta be it. Even the host networking doc page didn’t really explain why you would use/need it, and the networking page doesn’t seem to mention not retaining the IP so seems like something you just have to know from advanced use

Looks like host mode doesn’t work with docker for windows, so I’ll try to figure out the ipvlan way.

I am afraid none of those modes work with any Docker Desktop flavor, as they run the docker engine in a vm within an isolated ip range.

1 Like

So if I put it on say aws and set it to host mode it should work or I have to configure the advanced network stuff?

I’m reading up on the network modes, thanks for saving me additional time lol I was going in circles

yes

It would also work, if you install docker-ce in WSL and run your client application in the same wsl distribution and start the container on that docker instance with --network=host.

Note: WSL distributions do not come with systemd, as such you need to start the docker engine manually with sudo service docker start the first time this particular wsl distribution is started.

1 Like