Icecast Audio Streaming Server Installation

Icecast is a free, open-source audio streaming server that powers internet radio stations, podcast streams, and live audio broadcasts by accepting source client connections and distributing them to listeners over HTTP. With support for MP3, Ogg Vorbis, Opus, and AAC formats, Icecast can be integrated with automation tools like Liquidsoap to build fully automated radio stations on a Linux VPS.

Prerequisites

  • Ubuntu 20.04+, Debian 11+, or CentOS/Rocky 8+
  • Root or sudo access
  • Open ports: TCP 8000 (Icecast default), TCP 8443 (HTTPS optional)
  • A source client (Butt, Mixxx, VirtualDJ, Liquidsoap, etc.)

Installing Icecast

Ubuntu/Debian:

sudo apt update && sudo apt install -y icecast2

# The installer will prompt for:
# - Hostname (your server's domain or IP)
# - Source password (used by source clients to stream)
# - Relay password (for relay connections)
# - Admin password (for the web admin interface)

# Enable and start
sudo systemctl enable --now icecast2
sudo systemctl status icecast2

CentOS/Rocky Linux:

# Enable EPEL
sudo dnf install -y epel-release
sudo dnf install -y icecast

# Start the service
sudo systemctl enable --now icecast

Allow through firewall:

# Ubuntu/Debian
sudo ufw allow 8000/tcp

# CentOS/Rocky
sudo firewall-cmd --add-port=8000/tcp --permanent
sudo firewall-cmd --reload

Basic Configuration

The main configuration file is /etc/icecast2/icecast.xml:

sudo nano /etc/icecast2/icecast.xml

Key configuration sections:

<icecast>
  <location>Earth</location>
  <admin>[email protected]</admin>

  <!-- Stream limits -->
  <limits>
    <clients>100</clients>
    <sources>2</sources>
    <queue-size>524288</queue-size>
    <client-timeout>30</client-timeout>
    <header-timeout>15</header-timeout>
    <source-timeout>10</source-timeout>
    <burst-on-connect>1</burst-on-connect>
    <burst-size>65535</burst-size>
  </limits>

  <!-- Passwords -->
  <authentication>
    <source-password>hackme</source-password>   <!-- Change this! -->
    <relay-password>hackme</relay-password>     <!-- Change this! -->
    <admin-user>admin</admin-user>
    <admin-password>hackme</admin-password>     <!-- Change this! -->
  </authentication>

  <!-- Hostname used in stream URLs -->
  <hostname>radio.example.com</hostname>

  <!-- Network binding -->
  <listen-socket>
    <port>8000</port>
    <!-- Bind to all interfaces -->
    <bind-address>0.0.0.0</bind-address>
  </listen-socket>

  <!-- Admin web interface files -->
  <paths>
    <basedir>/usr/share/icecast2</basedir>
    <logdir>/var/log/icecast2</logdir>
    <webroot>/usr/share/icecast2/web</webroot>
    <adminroot>/usr/share/icecast2/admin</adminroot>
  </paths>

  <!-- Logging -->
  <logging>
    <accesslog>access.log</accesslog>
    <errorlog>error.log</errorlog>
    <loglevel>3</loglevel>   <!-- 1=error, 2=warn, 3=info, 4=debug -->
  </logging>
</icecast>
# Restart after configuration changes
sudo systemctl restart icecast2

# Verify it's listening
sudo ss -tlnp | grep 8000

Source Client Setup

Using BUTT (Broadcast Using This Tool) — GUI client:

  1. Open BUTT → Settings > Main
  2. Under Server, click Add
  3. Set:
    • Type: Icecast
    • Address: your-server.example.com
    • Port: 8000
    • Password: your source password
    • Mount: /stream

Using FFmpeg as a source client:

# Stream an audio file to Icecast
ffmpeg -re \
  -i /music/playlist.mp3 \
  -c:a libmp3lame -b:a 128k \
  -content_type audio/mpeg \
  -f mp3 \
  icecast://source:password@localhost:8000/stream

# Stream from microphone (ALSA)
ffmpeg \
  -f alsa -i default \
  -c:a libopus -b:a 128k \
  -content_type application/ogg \
  -f ogg \
  icecast://source:password@localhost:8000/stream.ogg

# Stream a live MP3 continuously with a playlist
ffmpeg \
  -f concat -safe 0 -i playlist.txt \
  -stream_loop -1 \
  -c:a libmp3lame -b:a 192k \
  -f mp3 \
  icecast://source:password@localhost:8000/radio.mp3

Mount Points

Mount points define individual streams. Configure them in icecast.xml:

<!-- Default fallback mount point -->
<mount type="default">
  <public>1</public>
  <stream-name>My Radio Station</stream-name>
  <stream-description>24/7 Music</stream-description>
  <stream-url>https://radio.example.com</stream-url>
  <genre>Mixed</genre>
  <bitrate>128</bitrate>
  <type>audio/mpeg</type>
</mount>

<!-- Specific mount with authentication -->
<mount>
  <mount-name>/private</mount-name>
  <password>secretpassword</password>   <!-- Override source password -->
  <max-listeners>10</max-listeners>
  <public>0</public>
  <stream-name>Private Stream</stream-name>
</mount>

<!-- High-quality mount -->
<mount>
  <mount-name>/hq</mount-name>
  <max-listeners>50</max-listeners>
  <bitrate>320</bitrate>
  <stream-name>My Radio HQ</stream-name>
</mount>

Access your stream:

Audio stream URL: http://radio.example.com:8000/stream
Admin interface:  http://radio.example.com:8000/admin/
Status page:      http://radio.example.com:8000/status.xsl

Relay Configuration

Relay another Icecast server's stream to distribute load:

<!-- In icecast.xml, add a relay block -->
<relay>
  <server>source-radio.example.com</server>
  <port>8000</port>
  <mount>/original</mount>
  <local-mount>/relayed</local-mount>
  <relay-shoutcast-metadata>1</relay-shoutcast-metadata>
</relay>

Master-slave relay (relay all mounts from master):

<master-server>master-icecast.example.com</master-server>
<master-server-port>8000</master-server-port>
<master-update-interval>120</master-update-interval>
<master-password>relaypassword</master-password>

Liquidsoap Integration

Liquidsoap automates stream programming with playlists, jingles, and dynamic content:

# Install Liquidsoap
sudo apt install -y liquidsoap

Create a basic Liquidsoap script:

sudo tee /etc/liquidsoap/radio.liq <<'EOF'
# settings
set("log.file.path", "/var/log/liquidsoap/radio.log")
set("server.telnet", true)
set("server.telnet.port", 1234)

# Define the main music playlist
music = playlist(mode="randomize", "/music/playlist/")

# Add jingles every 30 minutes
jingles = playlist(mode="randomize", "/music/jingles/")
radio = rotate(weights=[1, 8], [jingles, music])

# Apply normalization
radio = normalize(radio)

# Output to Icecast
output.icecast(
  %mp3(bitrate=128),
  host = "localhost",
  port = 8000,
  password = "hackme",
  mount = "/radio.mp3",
  name = "My Automated Radio",
  description = "24/7 Music Automation",
  genre = "Mixed",
  radio
)
EOF
# Create systemd service for Liquidsoap
sudo tee /etc/systemd/system/liquidsoap.service <<'EOF'
[Unit]
Description=Liquidsoap Radio Automation
After=icecast2.service

[Service]
User=liquidsoap
ExecStart=/usr/bin/liquidsoap /etc/liquidsoap/radio.liq
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now liquidsoap

Listener Statistics

Access stats via the web interface:

# Status page (no auth required)
curl "http://localhost:8000/status.xsl"

# JSON stats via admin API
curl -u admin:adminpassword \
  "http://localhost:8000/admin/stats" | \
  python3 -c "import sys; import xml.dom.minidom; print(xml.dom.minidom.parse(sys.stdin).toprettyxml())"

Parse listener counts:

# Get current listener count for a mount
curl -s -u admin:adminpassword \
  "http://localhost:8000/admin/listclients?mount=/stream" | \
  grep -c "<ID>"

# Log listener stats to file
while true; do
  COUNT=$(curl -s -u admin:adminpassword \
    "http://localhost:8000/admin/listclients?mount=/stream" | \
    grep -c "<ID>")
  echo "$(date +%Y-%m-%d\ %H:%M:%S) listeners=$COUNT" >> /var/log/icecast-stats.log
  sleep 60
done

Troubleshooting

Source client cannot connect:

# Check Icecast is running and listening
sudo systemctl status icecast2
sudo ss -tlnp | grep 8000

# Verify source password in icecast.xml
grep source-password /etc/icecast2/icecast.xml

# Check error log
sudo tail -f /var/log/icecast2/error.log

Listeners disconnect frequently:

# Increase queue size in icecast.xml
# <queue-size>1048576</queue-size>  (1 MB instead of 512 KB)

# Increase burst size
# <burst-size>131072</burst-size>

# Check network bandwidth
iftop -i eth0

Stream metadata not updating:

# Metadata is sent by the source client via HTTP PUT
# Test manually
curl -X PUT \
  -u source:password \
  "http://localhost:8000/admin/metadata?mount=/stream&mode=updinfo&song=Artist+-+Title"

Conclusion

Icecast provides a stable, lightweight audio streaming foundation that can scale from a simple personal radio station to a high-traffic broadcast serving thousands of simultaneous listeners through relay chains. Combining Icecast with Liquidsoap automation creates a fully self-hosted internet radio infrastructure with playlist management, jingles, and live DJ override capabilities — all running on a modest VPS without expensive licensing or usage fees.