Stream OBS audio to a self-hosted Icecast 2 server
Skip the managed platforms. Run Icecast yourself, point Radio Streamer at it, and broadcast on your own terms. The whole setup fits in a $5/month VPS.
Published 2026-05-08 / 12 minute read

Why self-host Icecast
Managed Icecast platforms are easy and there is nothing wrong with them. AzuraCast, Centova Cast, and Sonix all wrap Icecast with a friendly UI and handle hosting for you. But when you self-host, you get a few real advantages:
- Cost. A small VPS at Hetzner, DigitalOcean, or Linode runs Icecast for $5 a month and supports hundreds of concurrent listeners.
- Control. Mount points, listener limits, listener auth, fallback chains, and TLS are all yours to configure.
- Privacy. No third party sees your listener traffic.
- Simplicity for a single-source rig. Icecast is a few hundred KB binary with one config file. For one OBS rig pushing one mount, AzuraCast is overkill.
This guide covers the end-to-end path: install Icecast, configure it, open the port, and point Radio Streamer in OBS at the result.
What you need
- A server. A $5 VPS works fine for a few hundred listeners. A local Mac on your LAN works for testing.
- Icecast 2.4 or later. (Icecast 2.5 is current as of 2026.)
- OBS Studio 31.x with the Radio Streamer plugin installed (install steps).
- An open inbound TCP port on the server (8000 is the convention).
- Optional: a hostname pointed at the server. Raw IP works for testing.
Step 1: Install Icecast 2
Pick the install method that matches your server.
macOS (Homebrew)
brew install icecast
Config file: /opt/homebrew/etc/icecast.xml
Debian / Ubuntu
sudo apt install icecast2
Config file: /etc/icecast2/icecast.xml. The installer will prompt for initial passwords; you can change them later.
Docker (any host)
docker run -d --name icecast \ -p 8000:8000 \ -e ICECAST_SOURCE_PASSWORD=hunter2 \ -e ICECAST_ADMIN_PASSWORD=changeme \ -e ICECAST_HOSTNAME=radio.example.com \ moul/icecast
Override the bundled config by mounting your own icecast.xml into the container.
Step 2: Edit icecast.xml
Most of the default config is fine. The fields that matter:
<hostname>: your server's hostname or IP. Used to construct admin and listener URLs.<source-password>: anyone with this password can broadcast. Use a strong, unique value.<admin-password>: gives access to /admin/. Use a different strong password.<listen-socket><port>: usually 8000.
Minimum working snippet:
<icecast>
<hostname>radio.example.com</hostname>
<listen-socket>
<port>8000</port>
</listen-socket>
<authentication>
<source-password>hunter2</source-password>
<admin-user>admin</admin-user>
<admin-password>changeme</admin-password>
</authentication>
</icecast>
Mounts auto-create when a source connects. If you want a pre-configured mount with listener limits, add a block:
<mount type="default"> <mount-name>/live.mp3</mount-name> <max-listeners>200</max-listeners> <public>1</public> </mount>
Step 3: Start Icecast and open the port
Start the service:
brew services start icecast # macOS sudo systemctl enable --now icecast2 # Debian/Ubuntu
Confirm it is running locally:
curl -I http://localhost:8000/
You should get a 200 response.
Now make sure port 8000 is reachable from your OBS Mac:
- Cloud security group: allow inbound TCP 8000 from your IP (or 0.0.0.0/0 for public).
- Host firewall:
sudo ufw allow 8000/tcpon Ubuntu. - Residential router: port-forward 8000 to your local Icecast box.
Test from a different network:
curl -I http://radio.example.com:8000/
Step 4: Build the Icecast source URL
The format Radio Streamer (and FFmpeg under the hood) accepts:
icecast://username:password@host:port/mountpoint
For a self-hosted Icecast, the username is conventionally source and the password is whatever you set as <source-password>:
icecast://source:hunter2@radio.example.com:8000/live.mp3
The mount path can be anything. The file extension should match the codec you broadcast with: .mp3 for MP3, .aac for AAC, .opus or .ogg for Opus. Mismatched codec and mount returns a 4xx error.
URL-encode special characters in the password. @ becomes %40, : becomes %3A, # becomes %23.
Step 5: Configure Radio Streamer in OBS
- Open OBS Studio.
- Open
Docks > Radio Streamer. Enable the dock if it is hidden. - Paste the source URL into the URL field.
- Pick a codec matching the mount extension and a sensible bitrate (128 kbps for talk, 192 kbps for music).
- Pick the OBS audio track that carries your radio mix. Track 2 is the conventional choice (mic, music, and call-in routed to it via
Advanced Audio Properties, while Track 1 carries the main video stream's audio). - Enable Reconnect.
- Click Start.
Step 6: Verify
- Open
http://radio.example.com:8000/in a browser. You should see the public Icecast status page with your mount listed. - Open
http://radio.example.com:8000/admin/, log in with admin credentials, and confirm the active source is shown. - Open the mount URL directly:
http://radio.example.com:8000/live.mp3. The browser plays the live stream.
If the source connects but listeners hear nothing, the OBS audio track you selected has no sources routed to it. Open Audio Mixer in OBS, click the gear, choose Advanced Audio Properties, and confirm at least one source has the chosen track checked.

Common gotchas
icecast.xml syntax errors prevent the service from starting
Run Icecast directly with the config file path to see the parse error:
icecast -c /opt/homebrew/etc/icecast.xml
401 Unauthorized when Radio Streamer connects
Wrong source password, or special characters not URL-encoded. Test the same credentials with butt or ezstream first to isolate the issue.
Connection refused or timeout
Icecast is running but the port is firewalled. Walk through cloud security group, host firewall, and (if applicable) router port-forward in order. curl -v http://host:port/ from outside the server tells you which layer is blocking.
SELinux on RHEL/Fedora denies the bind
sudo setsebool -P httpd_can_network_connect on or run Icecast in a more permissive context.
Going further
- TLS via reverse proxy. Caddy is the simplest way: one block in Caddyfile gives you https://radio.example.com/ with auto-renewing certs proxied to Icecast. Source connections still use plain Icecast on 8000; only listener URLs become HTTPS.
- Listener auth. Define a mount with
<authentication type="htpasswd">if you want gated streams. - Liquidsoap fallback. Run Liquidsoap in front of Icecast to auto-rotate music when no source is live, then hand off to OBS when you go on air.
- Move to AzuraCast later. If you outgrow plain Icecast, the AzuraCast walkthrough covers the same OBS side, just pointed at AzuraCast's source mount.
Wrap up
The whole setup is about thirty minutes the first time, then under a minute for any future Icecast you spin up. The OBS side does not care whether the server is yours, AzuraCast, or anything else Icecast-compatible.
Found a step that needs updating? Open an issue on the GitHub repository.
