Icecast services behind Traefik

Hi guys!

I am working with traefik for quite some time and it works awesome. However, we are trying to get a icecast server to run in our cluster to be able to create a radio stream. So far I got it working, can access the admin interface. However, when I try to stream audio to it the connection is killed after 11 seconds.

I send the audio to the icecast service using HTTPs requests, however after 11 seconds I see that the server sends a TCP RST package. This will make the connection drop and reset.

I have no idea why this happens. Anyone an idea why this happens and how I can fix it?

Hello Matthijs,

I'm stuck with the same problem. If you have found a solution, I would be glad to hearit. I myself am routing 5 services correctly with traefik, only the icecast service somehow kills the connection every 10-11 seconds.


[2021-01-13  03:34:46] INFO connection/_handle_source_request Source logging in at mountpoint "/mount.ogg" from 192.168.192.9
[2021-01-13  03:34:46] WARN format/format_get_type Unsupported or legacy stream type: "audio/mpeg". Falling back to generic minimal handler for best effort.
[2021-01-13  03:34:46] INFO source/source_main listener count on /mount.ogg now 0
[2021-01-13  03:34:57] WARN source/get_next_buffer Disconnecting source due to socket timeout

I think I got it working.

    labels:
      - traefik.tcp.routers.icecast-streaming.rule=HostSNI(`*`)
      - traefik.tcp.routers.icecast-streaming.entrypoints=web2
      - traefik.tcp.routers.icecast-streaming.service=icecast-streaming
      - traefik.tcp.services.icecast-streaming.loadbalancer.server.port=8080

      - traefik.http.routers.icecast.rule=Host(`icecast.chabaa`)
      - traefik.http.routers.icecast.entrypoints=web2,web
      - traefik.http.routers.icecast.service=icecast
      - traefik.http.services.icecast.loadbalancer.server.port=8080

When posting the question, I already had the idea of routing the tcp traffic, but still had to tweak it a little

- --entrypoints.web.address=:80
- --entrypoints.web2.address=:8080

I too sniffed the docker network traffic and got the TCP RST package. What put me on the track was that TCP packages to the trafik service did not route anywhere, so adding the tcp routing label was the solution.

Thanks, for anybody still having put a thought into it.

1 Like

A bit late to the party, but here's what I used, l leveraging your notes, to allow TLS ingest with name-based routing (SNI) for multiple concurrent instances to run and have encoders connect to the proper instance. Leaving out the HTTP/HTTPS routers, as those are as standard as can be.

labels:
      - "traefik.tcp.services.{{ service }}-tcp.loadbalancer.server.port=8080"
      - "traefik.tcp.routers.{{  service }}-tcp.service={{ service }}-tcp"
      - "traefik.tcp.routers.{{  service }}-tcp.rule=HostSNI(`{{ domain }}`)"
      - "traefik.tcp.routers.{{  service }}-tcp.entrypoints=encoders"
      - "traefik.tcp.routers.{{  service }}-tcp.tls=true"
      - "traefik.tcp.routers.{{  service }}-tcp.tls.certresolver=leresolver"

Hello everyone ! I'm facing the same issue using traefik v2.9.6 and it seems that jesseorr's solutions didn't worked for me. Here's my config for icecast, in case someone has an idea :slight_smile:
Have a good day !

version: '3.1'
services:
  icecast:
    image: perl19/icecast2:latest
    secrets:
      - icecast_password
    environment:
      - IC_AUTH_ADMIN=admin
      - IC_AUTH_ADMIN_PASS=/run/secrets/icecast_password
      - IC_SOURCE_PASS=password
      - IC_HOSTNAME=player.myradio.ch
      - IC_PORT=8000
      - IC_LIMITS_CLIENTS=1000
      - IC_LIMITS_SOURCES=2
      - IC_LIMITS_QUEUE_SIZE=524288
      - IC_LIMITS_BURST_SIZE=65535
      - IC_LIMITS_CLIENT_TIMEOUT=30
      - IC_LIMITS_HEADER_TIMEOUT=15
      - IC_LIMITS_SOURCE_TIMEOUT=10
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.constraint-label=traefik-public"
        - "traefik.tcp.services.icecast-tcp.loadbalancer.server.port=8000"
        - "traefik.tcp.routers.icecast-tcp.service=icecast-tcp"
        - "traefik.tcp.routers.icecast-tcp.rule=HostSNI(`icecast-dev.myradio.ch`)"
        - "traefik.tcp.routers.icecast-tcp.entrypoints=https"
        - "traefik.tcp.routers.icecast-tcp.tls=true"
        - "traefik.tcp.routers.icecast-tcp.tls.certresolver=le"
        - traefik.http.routers.icecast-http.rule=Host(`icecast-dev.myradio.ch`)
        - traefik.http.routers.icecast-http.entrypoints=http
        - traefik.http.routers.icecast-http.middlewares=https-redirect
        - traefik.http.routers.icecast-https.rule=Host(`icecast-dev.myradio.ch`)
        - traefik.http.routers.icecast-https.entrypoints=https
        - traefik.http.routers.icecast-https.tls=true
        - traefik.http.routers.icecast-https.service=icecast
        - traefik.http.services.icecast.loadbalancer.server.port=8000
    networks:
      - traefik-public
secrets:
  icecast_password:
     external: true
networks:
  # Use the previously created public network "traefik-public", shared with other
  # services that need to be publicly available via this Traefik
  traefik-public:
    external: true

What’s your problem?

Can you share your Traefik static/dynamic config and used docker-compose.yml?

You are using Docker Swarm, how do you deploy your services, is it a stack?

It’s a paid TLS/SSL cert explicitly for the domain?

Have you looked at your Traefik dashboard and Traefik debug logs and access logs?

Got it working with the following docker compose:

networks:
  traefik:
    external: true

services:
  icecast:
    image: ice:dev
    build: .
    restart: unless-stopped
    labels:
      - 'traefik.enable=true'
      # TCP router, handle streaming to Icecast
      # !! Works only with HostSNI(*) and TLS off !!
      - 'traefik.tcp.routers.icecast-tcp.rule=HostSNI(`*`)'
      - 'traefik.tcp.routers.icecast-tcp.entrypoints=http'
      - 'traefik.tcp.routers.icecast-tcp.tls=false'
      - 'traefik.tcp.routers.icecast-tcp.service=icecast-tcp'
      - 'traefik.tcp.services.icecast-tcp.loadbalancer.server.port=8000'
      # HTTP router, redirect to HTTPS
      - "traefik.http.routers.icecast-insecure.rule=Host(`ice.example.com`)"
      - 'traefik.http.routers.icecast-insecure.entrypoints=http'
      - 'traefik.http.routers.icecast-insecure.middlewares=redirect-secure'
      # HTTPS router
      - "traefik.http.routers.icecast.rule=Host(`ice.example.com`)"
      - 'traefik.http.routers.icecast.entrypoints=https'
      - 'traefik.http.routers.icecast.tls.certresolver=le'
      - 'traefik.http.routers.icecast.service=icecast'
      - 'traefik.http.services.icecast.loadbalancer.server.port=8000'
    networks:
      - traefik
    volumes:
      - ./icecast.xml:/etc/icecast.xml

This is my Dockerfile:

FROM alpine:3.16

RUN apk add --no-cache icecast

EXPOSE 8000

ENTRYPOINT ["icecast", "-c", "/etc/icecast.xml"]

Traefik is configured with only http/s entrypoints:

      - --entryPoints.http.address=:80
      - --entryPoints.https.address=:443

Icecast2 is configured with ice.example.com hostname.

Streaming works on ice.example.com:80 (no TLS), while listening works on https://ice.example.com.