Mediasoup behind Docker Swarm + Kong: Host network and port exposure issues

Hi everyone,

I’m trying to deploy a Mediasoup backend in a Docker Swarm stack with multiple services, including other services and Kong as API gateway. I have problem in expose Mediasoup UDP/TCP ports to public clients.

Here’s my current setup:

webRtcServerOptions: {
  listenInfos: [
    { protocol: "udp", ip: "0.0.0.0", announcedAddress: process.env.MEDIASOUP_ANNOUNCED_IP, port: 44444 },
    { protocol: "tcp", ip: "0.0.0.0", announcedAddress: process.env.MEDIASOUP_ANNOUNCED_IP, port: 44444 },
  ],
},
webRtcTransportOptions: {
  listenInfos: [
    { protocol: "udp", ip: "0.0.0.0", announcedAddress: process.env.MEDIASOUP_ANNOUNCED_IP, portRange: { min: 40000, max: 40099 } },
    { protocol: "tcp", ip: "0.0.0.0", announcedAddress: process.env.MEDIASOUP_ANNOUNCED_IP, portRange: { min: 40000, max: 40099 } },
  ],
},

Initially, I tried using overlay network for all services and mapping ports:

ports:
  - "44444:44444"
  - "40000-40099:40000-40099/udp"
  - "40000-40099:40000-40099/tcp"

this is how my docker compose file look like

version: "3.9"

services:
  backend:
    image: myregistry/backend:latest
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    ports:
      - "4443:4443" # my backend https/wss port 
      - "44444:44444" # Webrtc Server port
      - "40000-40099:40000-40099/udp"
      - "40000-40099:40000-40099/tcp"
    env_file:
      - ./docker/configs/env/backend.env
    depends_on:
      - db
    networks:
      - meetings

  db: 
    image: myregistry/mongo:latest
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: DB_USER
      MONGO_INITDB_ROOT_PASSWORD: DB_PASS
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
    networks:
      - meetings

  # other services ..............

  kong-database:
    image: myregistry/postgres:latest
    hostname: kong-database
    environment:
      POSTGRES_USER: KONG_USER
      POSTGRES_DB: KONG_DB
      POSTGRES_PASSWORD: KONG_PASS
    networks:
      - meetings
    restart: always
    volumes:
      - /mnt/kong_data:/var/lib/postgresql/data

  kong:
    image: myregistry/kong:latest
    hostname: kong
    environment:
      KONG_PG_HOST: kong-database
      KONG_DATABASE: postgres
      KONG_PG_USER: KONG_USER
      KONG_PG_PASSWORD: KONG_PASS
      KONG_PROXY_LISTEN: 0.0.0.0:8443 ssl
      KONG_ADMIN_LISTEN: 0.0.0.0:8444
      NGINX_PROXY_PROXY_BUFFER_SIZE: 128k
      NGINX_PROXY_PROXY_BUFFERS: 4256k
      NGINX_PROXY_PROXY_BUSY_BUFFERS_SIZE: 256k
      KONG_NGINX_WORKER_PROCESSES: 32
    depends_on:
      - kong-database
    networks:
      - meetings
    ports:
      - "8443:8443"
      - "8444:8444"
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    security_opt:
      - no-new-privileges

volumes:
  mongo_data:

networks:
  meetings:
    driver: overlay
    attachable: true

backend.env

# -------------------
# MediaSoup
# -------------------
MEDIASOUP_LISTEN_IP=0.0.0.0
MEDIASOUP_ANNOUNCED_IP=my_public_ip_address
MEDIASOUP_MIN_PORT=40000
MEDIASOUP_MAX_PORT=40099

This setup works properly on my VM’s private IP, but when I forward the services through the Kong API gateway, it does not work for public users using the public IP. I have already exposed ports 44444 and 40000–40099 from my route to the public IP.