Search code examples
linuxdockernetwork-programmingdocker-composemulticast

Multicast in Docker container and on standalone desktop application not working


I have an application (UI) that monitors multicast streams to see if the streams are working correctly. On top of that, I have a docker container (that runs in "network_mode: host") that also listens to the multicast streams and cache them in a database.

The compose file looks like this :

version: "3"
services:
  my-multicast-container:
    image: my-multicast-container-image:latest
    depends_on:
      - my-database
    network_mode: host
  my-database:
    image: my-database-image:latest
    restart: always
    ports:
      - ... #forwarded ports for the other container

My issue is : when I listen to the multicast streams inside my docker container, the monitoring application that runs on the same host as the docker isn't able to listen to the same streams that the docker is listening to. As I've read online, it's not possible to listen to multicast in a docker container without "network_mode: host" because of how containers works,... and can't seem to find a solution to that problem.

How can I receive the multicast packets in my docker container and in my desktop application ?

FYI: don't know if it's important but I'm using CentOS as a host OS


Solution

  • The problem was not really about multicast but, in fact, was about the user which owns the multicast UDP socket.

    By default, the docker container is started as root user and the monitoring interface is started with the host's user. And, as mentioned in the SO_REUSEPORT documentation :

    To prevent unwanted processes from hijacking a port that has already been bound by a server using SO_REUSEPORT, all of the servers that later bind to that port must have an effective user ID that matches the effective user ID used to perform the first bind on the socket.

    So, to re-use the socket, the solution was to use the host's user to run the docker container like this :

    docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) --network=host \
     my-multicast-container-image:latest