Opening RTMP (TCP) port for multiple Owncast containers

Hi there.

I'm attempting to configure Traefik to redirect to multiple Owncast containers. Each of which would ideally accept RTMP streams at:

rtmp://owncast1.exampleurl.com:1935/live
rtmp://owncast2.exampleurl.com:1935/live

etc. (Where obviously exampleurl.com is something else)

The current staging environment is a Pi 5 running behind my home firewall with port 1935 exposed and directing to the Pi. Ports 80 and 443 are also open and directing to the Pi, and I don't want to open any more. I am using a LetsEncrypt certificate to ensure https, and I believe this should also work for HostSNI TCP configurations.

The relevant points of configuration are:

traefik.yml

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: leresolver
  rtmp:
    address: ":1935/tcp"

certificatesResolvers:
 leresolver:
    acme: [...]

traefik docker-compose.yml

services:
  traefik-reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:latest
    restart: unless-stopped
    ports:
      # The HTTP port
      - "80:80"
      # The HTTPS port
      - "443:443"
      # The Web UI
      - "8080:8080"
      # rtmp port
      - "1935:1935"

owncast1 docker-compose.yml

ports:
      - "1935:1935"
labels:
      - "traefik.enable=true"

      - "traefik.http.routers.owncast1.rule=Host(`owncast1.exampleurl.com`)"
      - "traefik.http.routers.owncast1.entrypoints=websecure"
      - "traefik.http.routers.owncast1.service=owncast1-service"
      - "traefik.http.services.owncast1-service.loadbalancer.server.port=8080"
      - "traefik.http.routers.owncast1.tls=true"
      - "traefik.http.routers.owncast1.tls.certresolver=leresolver"

      - "traefik.tcp.routers.owncast1-tcp.rule=HostSNI(`owncast1.exampleurl.com`)"
      - "traefik.tcp.routers.owncast1-tcp.entrypoints=rtmp"
      - "traefik.tcp.routers.owncast1-tcp.service=owncast1-tcp-service"
      - "traefik.tcp.routers.owncast1-tcp.tls=true"
      - "traefik.tcp.routers.owncast1-tcp.tls.certresolver=leresolver"
      - "traefik.tcp.services.owncast1-tcp-service.loadbalancer.server.port=1935"

This works for a single Owncast container, but when I try to compose up another (renaming owncast1 to owncast2 in the docker-compose, I first get an error that port 1935 is in use. Changing configuration to:

ports:
      - "1936:1935"
labels:
[...]
      - "traefik.tcp.services.owncast2-tcp-service.loadbalancer.server.port=1936"

doesn't work as expected, as any rtmp calls to 'rtmp://owncast2.exampleurl.com:1935/live' are instead serviced by the first owncast instance.

Can Traefik be configured in this manner? Multiple containers in the network each receiving tcp/ rtmp traffic to the external port 1935? Ideally with the container's internal port also being 1935.

And if so, what am I doing wrong?

https requests work fine in this configuration, and are correctly passed to the expected Owncast containers. So I presume there's something not quite hitting the HostSNI check for rtmp even if TLS is enabled.

Traefik target services should not use ports to open ports for listening on host. This enables potential circumventing of Traefik security measures like middlewares.

Instead Traefik and target services should share a Docker network, where all ports are internally accessible anyway.

For RTMP to work through Traefik, it needs to use HTTP with Host header or TCP TLS with HostSNI. Without, Traefik can not match it to a router/service.

It can then still work with TCP HostSNI(`*`), but that targets only a single service. If you have multiple target Docker containers, you could try using the same labels and hoping for round-robin distribution.

Alternatively use Docker Swarm to create Docker services with multiple instances.