Software Stack
Install all the components on the Pi:
sudo apt install mpd mpc icecast2 nginx python3 sqlite3 -y
MPD — Music Player Daemon
MPD is the playback engine. It reads your music files, manages a queue, and outputs audio. In this setup it streams to Icecast2 rather than playing through speakers.
After installing, stop the default service — you'll configure it before starting:
sudo systemctl stop mpd
sudo systemctl disable mpd # we'll manage it ourselves
Icecast2 — Streaming Server
Icecast2 receives the audio from MPD and serves it as an HTTP stream. Clients (browsers, music players) connect to http://your-pi:8000/radio.mp3 to listen.
During installation, the package will prompt you for passwords. You can set them now or configure them later in /etc/icecast2/icecast.xml.
sudo systemctl enable icecast2
Nginx — Reverse Proxy
Nginx serves the web frontend on port 80 and proxies API requests to the Python server on port 5000. It also proxies the Icecast stream so everything is accessible on a single host.
sudo systemctl enable nginx
Python — API Server
The API server is a plain Python 3 HTTP server using only the standard library — no pip, no virtualenv, no frameworks. It handles playlist data, song tagging, stats, and the programming schedule.
Python 3 ships with Raspbian. No additional packages needed.
SQLite3 — Database
SQLite stores the song catalogue, play history, skips, and tags. The database lives at /var/www/radio/db.sqlite3. The sqlite3 CLI is useful for ad-hoc queries.
mpc — MPD Command-Line Client
mpc is a lightweight CLI client for MPD. The scheduler and playlist scripts use it to control playback and manage the queue.
mpc status # check what's playing
mpc ls # list available playlists
mpc load Rock # load a playlist
mpc play # start playback
Directory Layout on the Pi
/var/www/radio/
├── server.py # Python API server
├── setup_db.py # One-time DB schema init
├── db.sqlite3 # Song database
├── .env # Runtime secrets
└── public/ # Web frontend (served by Nginx)
/usr/local/bin/
├── song_logger.sh
├── radio_scheduler.sh
├── create_playlists.sh
├── mpd_watchdog.sh
└── generate_stationid_hours.sh
/var/log/
└── radio_playlist.log # One entry per song played (4 lines each)