Installation
Application Files
The application is deployed from a development machine to the Pi using rsync. The repo contains a Makefile with all the deployment targets — you never SSH in to make changes manually.
Create the application directory on the Pi:
sudo mkdir -p /var/www/radio/public
sudo chown -R YOUR_USER:www-data /var/www/radio
Deploy the files from your dev machine:
rsync -av server/ pi-user@your-pi:/var/www/radio/
rsync -av public/ pi-user@your-pi:/var/www/radio/public/
Initialise the Database
On the Pi, run the setup script once to create the SQLite schema:
cd /var/www/radio
python3 setup_db.py
This creates the songs, tags, plays, and skips tables.
Install Scripts
Copy the shell scripts to /usr/local/bin/ and make them executable:
sudo cp scripts/*.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/*.sh
Systemd Services
Two services keep the station running:
pi3radio.service — the Python API server:
[Unit]
Description=Pi Radio Server
After=network.target
[Service]
Type=simple
User=YOUR_USER
WorkingDirectory=/var/www/radio
ExecStart=/usr/bin/python3 /var/www/radio/server.py
Restart=on-failure
RestartSec=5
EnvironmentFile=-/var/www/radio/.env
[Install]
WantedBy=multi-user.target
song-logger.service — watches MPD and logs every song:
[Unit]
Description=MPD Song Logger
After=mpd.service
[Service]
Type=simple
User=mpd
Group=audio
ExecStart=/usr/local/bin/song_logger.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Install and enable both:
sudo cp systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable pi3radio song-logger
sudo systemctl start pi3radio song-logger
Crontab
All cron jobs must run under your regular user — not root. Running them as root causes every job to fire twice.
crontab -e
Add:
0 * * * * /usr/local/bin/radio_scheduler.sh
0 3 * * 0 /usr/local/bin/create_playlists.sh
0 0 * * * /usr/local/bin/generate_stationid_hours.sh
@reboot sleep 60 && /usr/local/bin/radio_scheduler.sh
*/5 * * * * /usr/local/bin/mpd_watchdog.sh
Verify root has no radio cron jobs:
sudo crontab -l # should say "no crontab for root"
Environment File
Create /var/www/radio/.env with your API key:
OPENWEATHER_API_KEY=your_key_here
This is loaded by the systemd EnvironmentFile directive. The key is injected into the frontend JavaScript at deploy time — it never lives in the source code.
MPD Playlists
Build the initial playlists. This scans your music directory and generates genre-based .m3u files in /var/lib/mpd/playlists/:
/usr/local/bin/create_playlists.sh
Then start MPD and verify it's playing:
sudo systemctl start mpd
mpc status
Verify Everything
Check all services are running:
systemctl status mpd icecast2 nginx pi3radio song-logger
Open the web player in a browser:
http://your-pi-ip
Listen to the stream:
http://your-pi-ip:8000/radio.mp3