I am trying to create a python socket inside a docker and forward that port to its host machine, to where some other programs should be trying to connect.
For this, the dockerised running python is doing as follows:
# Python 3.8, inside docker
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 5000))
while True:
message, addrs = s.recvfrom(1480)
_log(f"DATA RECIEVED from {addrs}") # arbitrary logging function
Due to others programs not knowing in advance which range of ip's will be decided for the dockers network, i have to trust into docker's ports comunication. So, what i would like to achive is that, when the host is recievin any socket doing a connect in its 5000 port, it would be picked by the dockerised python.
Both server and dockerised image are ubuntus. The ip of the host in the local network is 192.168.1.141, the docker subnet is in 172.18.0.0, and docker-compose for the docker itself looks as follows:
docker-compose file
version: "3"
services:
my_docker:
container_name: python_socket
image: registry.gitlab.com/my_group/my_project:latest
volumes:
- ./configs:/configs
- ./logs:/configs/logs
- ./sniffing:/app/sniffing
ports:
- "5000:5000"
- "3788:3788"
- "3787:80"
networks:
- app_network
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- rabbitmq
- backend
restart: always
networks:
app_network:
With this configuration, I am not being able to connect. I've seen that, in the host, if I launch an Ipython and try the following:
# Python 3.8, ipython console
data = "Hello"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('172.18.0.2', 5000))
s.send(data.encode())
Then this info reaches the docker successfully. But if i try to connect to either 0.0.0.0:5000, localhost:5000 or 192.168.1.141:5000, then I only get connection errors. The docker is getting the information from outside the machine, either.
What am I missing? I have web servers simmilarly configured where the docker port forwarding is successful.
Thanks in advance for your time and help.
CodePudding user response:
You're creating a UDP socket (SOCK_DGRAM
). Compose ports:
is somewhat quiet on this feature, but the general Container networking overview implies that port forwarding defaults to TCP only.
You can explicitly specify you need to forward a UDP port:
ports:
- '5000:5000/udp'
Then you can connect to the host's DNS or IP address (or localhost
or 127.0.0.1, if you're calling from outside a container but on the same host) and the first port number 5000. Do not look up the container-private IP address; it's unnecessary and doesn't work in most contexts.