8.3 KiB
Setting Up Radio Free Elsewhere on Yunohost
This guide covers installing the Radio Free Elsewhere website on a Yunohost server: the public pages, the admin backend, the database and the track-history poller. It assumes Icecast is already running and streaming; setting up Icecast itself is not covered here.
You'll need:
- Admin access to the Yunohost web panel
- SSH access to the server with
sudo - An SFTP client
- A copy of this repository
Throughout this guide, my_webapp stands for the app's system user and /var/www/my_webapp/www stands for the site's folder. Yours may differ (a second install becomes my_webapp__2, for example), so substitute your own values wherever they appear.
1. Install the My Webapp app
The site is plain PHP with a MariaDB database, which is what Yunohost's My Webapp app provides.
- In the Yunohost admin panel, go to Applications → Install and choose My Webapp.
- Pick the domain and path for the site.
- Set an SFTP password. You'll use it to upload files.
- Choose a PHP version (8.1 or newer) and MySQL as the database.
- Install.
Yunohost creates a system user for the app, a PHP-FPM pool that runs as that user, and a database with its own database user.
Note the PHP version you picked. You'll need the matching command-line PHP for the cron job and the CLI tools.
2. Check PHP
The site needs these PHP extensions: pdo_mysql, mbstring and fileinfo. It also needs allow_url_fopen turned on, because it fetches the Icecast status and album art over HTTPS. These are normally present on Yunohost. To check over SSH, run:
ls /usr/bin/php* # find the CLI matching your chosen version, e.g. /usr/bin/php8.2
/usr/bin/php8.2 -m | grep -Ei 'pdo_mysql|mbstring|fileinfo'
/usr/bin/php8.2 -i | grep allow_url_fopen
Use that same versioned binary (for example /usr/bin/php8.2) everywhere this guide runs PHP. The plain php command may point to a different version that lacks the MySQL driver.
3. Upload the site
Connect over SFTP as the app user (my_webapp, with the password from step 1). Then upload the repository's contents into the site folder (www/), so that index.php sits at /var/www/my_webapp/www/index.php.
Don't upload .git, archive/ or unneededsections.html; the site doesn't need them.
On later deployments, never overwrite config/db_credentials.php or the contents of images/backgrounds/ on the server. Both belong to that server.
4. Create the database tables
Find the database name, database user and password Yunohost created:
sudo yunohost app setting my_webapp db_name
sudo yunohost app setting my_webapp db_user
sudo yunohost app setting my_webapp db_pwd
Then apply the schema. It creates the tables and adds the five shows, and it's safe to re-run:
cd /var/www/my_webapp/www
mysql -u <db_user> -p <db_name> < sql/schema.sql
If the database user lacks permission to create tables, run it as root instead:
sudo mysql <db_name> < sql/schema.sql
5. Add the database credentials
Copy the template, then edit the copy:
cd /var/www/my_webapp/www/config
sudo cp db_credentials.example.php db_credentials.php
sudo nano db_credentials.php
Fill in database, username and password with the values from step 4, and leave host, port and charset as they are.
Then make the file readable by the app user only:
sudo chown my_webapp:my_webapp db_credentials.php
sudo chmod 640 db_credentials.php
The web server and the cron job both run as the app user, so they can read it. The file is gitignored and is never committed.
6. Make the backgrounds folder writable
Show background images are uploaded through the admin pages into images/backgrounds/. The app user needs to be able to write there:
sudo chown my_webapp:my_webapp /var/www/my_webapp/www/images/backgrounds
sudo chmod 755 /var/www/my_webapp/www/images/backgrounds
Uploads are limited to 5 MB. PHP's post_max_size must be at least that; the default of 8 MB is fine.
7. Create an admin account
Create the account as the app user, so the script can read the credentials file:
cd /var/www/my_webapp/www
sudo -u my_webapp /usr/bin/php8.2 cli/create_admin.php <username>
You'll be prompted for a password of at least 12 characters. Running the same command again for an existing username resets that account's password. The site never sends email, so this command is the only way to reset a password.
Log in at /admin/ on your site to check it works.
8. Set up the track-history cron job
Don't skip this step. Without it, the recently played list on live.php stays empty and queued shows never go live, even though the now-playing widget looks fine. The widget reads Icecast directly; the recently played list only shows what the poller has saved to the database.
cli/poll_icecast.php must run once a minute. Each run checks Icecast four times, 15 seconds apart. It starts broadcasts when the stream comes online, records each new track and ends broadcasts once the stream has been gone for five minutes.
Test it by hand first
Start a stream, then run the poller as the app user:
sudo -u my_webapp /usr/bin/php8.2 /var/www/my_webapp/www/cli/poll_icecast.php
It takes about 45 seconds and prints nothing when it succeeds. The current track should then appear on live.php. If it prints an error instead, fix that before going on. The most common one is the credentials file not being readable by this user (see step 5).
Add the cron job
Create a cron file:
sudo nano /etc/cron.d/rfe-poll-icecast
Put this single line in it, with your user, PHP version and path, and finish the file with a newline:
* * * * * my_webapp /usr/bin/php8.2 /var/www/my_webapp/www/cli/poll_icecast.php 2>&1 | logger -t rfe-poll
Then set its ownership and permissions:
sudo chown root:root /etc/cron.d/rfe-poll-icecast
sudo chmod 644 /etc/cron.d/rfe-poll-icecast
Things to know about this file:
- Use
/etc/cron.d, not a personal crontab. It survives Yunohost upgrades, and its sixth field names the user the job runs as. - Run it as the app user, the same user PHP-FPM uses. Other users usually can't read the credentials file.
- Don't put a dot in the filename. Cron silently ignores files in
/etc/cron.dwhose names contain one, sorfe-poll-icecast.cronwould never run. - The file must be owned by root and not writable by anyone else, or cron ignores it.
- The
loggerpart keeps errors. Anything the poller prints goes to the system journal under the tagrfe-pollinstead of being thrown away.
Check it's running
After a couple of minutes, run:
journalctl -u cron --since "10 min ago" # the job should appear once a minute
journalctl -t rfe-poll --since "10 min ago" # poller errors; empty means all is well
During your next stream, tracks should start appearing on live.php within a minute.
9. Before each broadcast
-
Queue the show from the admin dashboard, or over SSH:
sudo -u my_webapp /usr/bin/php8.2 cli/set_show.php # list shows sudo -u my_webapp /usr/bin/php8.2 cli/set_show.php <slug> # queue one -
Start streaming. Within a minute, the poller starts the queued broadcast. The live page's heading and background switch to the show, and tracks begin to appear.
-
Point listeners to
live.php.
If you forget to queue a show, the broadcast is still recorded without one. You can assign a show from the dashboard while you're live.
Troubleshooting
The recently played list says "Nothing played yet" during a stream.
The poller isn't saving tracks. Check that the cron file exists and is named correctly (step 8). Look at journalctl -t rfe-poll for errors, and try the manual run while streaming.
The recently played list says "Unable to load recently played tracks".
The site can't reach the database. Check config/db_credentials.php and confirm the schema was applied (step 4).
The admin dashboard shows a queued show that never goes live. This is the same cause as an empty recently played list: the poller isn't running.
Background image uploads fail.
The app user can't write to images/backgrounds/ (see step 6), or the image is over 5 MB.
Tracks disappear after the show. That's expected. Track history is cleared ten minutes after a broadcast ends.