-
Notifications
You must be signed in to change notification settings - Fork 1
Unified Installer
An Ansible playbook that provisions a fresh Ubuntu 24.04/26.04 machine
(x64 or arm64) into a working Rivolution install end to end:
OS/desktop/xRDP setup, audio-hardware detection, installing Rivolution
itself, and network topology (standalone/server/client). Lives in its
own repo,
rivolution-unified-installer,
separate from the application repo so the two can move at different
paces.
By default this installs the project's own released .deb package —
downloaded straight from GitHub Releases, the same artifact everyone
else installs. From there, debian/postinst (maintained in
the main repo) does the real
provisioning: system users, /var/snd, the database, every
broadcast-stack systemd unit, sudoers, udev, .asoundrc, Apache
wiring, and more. This installer's job is getting a .deb onto the box
and telling apt to install it, plus the handful of things that
genuinely can't be a package's job (OS/desktop setup, audio-hardware
detection, network topology, Tailscale).
An opt-in rivolution_install_method: source builds a local .deb
from a git checkout instead of downloading one — useful for a private
fork, an unreleased branch, or a target with no published release asset
yet (Debian Trixie, currently). Either way, postinst runs the exact
same way from an identical apt install step.
Tip
Prefer filling in a form over hand-editing a script? rivolution.dev/configure.html builds the paste-in startup script below for you from a set of fields, live, entirely in your own browser — no network requests, nothing you type (including any password/key field) ever leaves the page.
./configure.sh is the interactive front end. It asks once for install
method (deb/source), install mode, install user (and, optionally, its
login password), Tailscale, and security hardening, then either pushes
over SSH to a separate host you give it, runs directly against the box
you're already logged into (no SSH needed — this is what you want if
you SSH'd into the target yourself and are running configure.sh on it
directly), or writes a fully filled-in script for you to paste into a
cloud provider's startup-script field for a box that doesn't exist yet.
The target itself never has to answer a prompt — by the time anything
runs unattended, every answer is already baked in.
Tip
If you choose the "run directly on this box" method and
./configure.sh isn't already running as root, it re-execs itself
under sudo right at that point — you'll be prompted for your
password there, same as running any other command with sudo,
without having to remember to start the script with sudo yourself.
If Ansible itself isn't installed yet, this method also installs it
automatically once it's root — safe to do unprompted, since the
target is already guaranteed to be Ubuntu/Debian. The SSH method
does neither of these, since it runs on whatever your control
machine happens to be.
git clone https://github.com/anjeleno/rivolution-unified-installer.gitcd rivolution-unified-installer && ./configure.shTo skip the interactive prompts entirely (e.g. a non-interactive local source-method install), pass the install method directly:
./configure.sh --method=local --install-method=sourceIf you'd rather skip the prompts, all three usage methods below also work by hand.
Requires Ansible already installed on this machine
(sudo apt update && sudo apt install -y ansible). For a Droplet, UTM
VM, or physical box that's already SSH-reachable as root (or any
sudo-capable user), run this from a separate machine:
- Add the target to
inventory/hosts.ini. - Install the required collections:
ansible-galaxy install -r requirements.yml- Run the playbook:
ansible-playbook site.ymlThe manual, by-hand equivalent of choosing "local" in ./configure.sh
above — not deprecated by it, just the non-interactive version.
Requires Ansible already installed on this box
(sudo apt update && sudo apt install -y ansible) — installed
system-wide via apt, not via pip install --user, since sudo
resets PATH and won't see a user-local install. If you're already
logged into the box, run this on that same box, as root or a user
with passwordless sudo (prefix both commands below with sudo if
you're not already root):
- Install the required collections:
ansible-galaxy install -r requirements.yml- Run the playbook directly against this machine:
ansible-playbook -i "localhost," -c local site.ymlAdd -e rivolution_install_method=source (or any other variable
override) to skip the deb default without going through
configure.sh at all:
ansible-playbook -i "localhost," -c local site.yml -e rivolution_install_method=sourcebootstrap.sh is meant to be pasted directly into DigitalOcean's
Droplet creation screen (Additional Options → Startup scripts (Free)),
or run as-is on a freshly installed UTM VM / physical box. It installs
Ansible and uses ansible-pull to fetch the repo and run site.yml
against the local machine — no inbound SSH or separate control node
required. Edit the variables at the top of
bootstrap.sh
first, then paste the whole script in.
By default this builds the public anjeleno/rivolution repo on
main — no access or key needed to use the defaults as-is.
-
deb(default) — downloads the matching release asset from GitHub Releases for this host's architecture (and, for amd64, its Ubuntu version — 26.04 gets the primary build, 24.04 gets the-noblebuild).rivolution_release_tag(blank = latest published release) can pin an exact version instead. -
source— clonesrivolution_git_repo/rivolution_git_ref(defaults to the public repo'smainbranch) and builds a real local.debfrom it, then installs that through the identical step thedebmethod uses. Use this for a private fork, an unreleased branch, or a target with no published release asset — currently, that means Debian Trixie.
rivolution_install_mode (default standalone) picks one of three
shapes, applied by driving the dashboard's own /mode page over HTTP
once Rivolution is installed and its dashboard is up:
- standalone — everything local: database, audio store, desktop.
- server — standalone, plus the database and audio store exposed to other Rivolution hosts over NFS.
- client — only the Rivolution application itself, pointed at a remote MySQL/MariaDB host and a remote NFS-mounted audio store instead of provisioning either locally.
Optional, and only ever applied at account-creation time — re-running
this playbook against a box that already has the account never resets
a password you've since changed by hand. Leave blank to leave the
account exactly as it was before (locked, login only via SSH key or an
already-authenticated sudo session). configure.sh prompts for it
securely; bootstrap.sh has a matching RIVOLUTION_USER_PASSWORD
variable.
rivolution_tailscale_enabled (default false) installs the
tailscale package and enables (but does not start) tailscaled, plus
a scoped sudoers grant for the install user to run tailscale up/cert/status. Leave rivolution_tailscale_authkey_path blank to
activate it yourself later (sudo tailscale up), or point it at a file
containing a real auth key to activate immediately during
provisioning. The key must be a real Tailscale auth key (always
tskey-auth-<letters/numbers>-<letters/numbers>, generated from the
admin console's Settings → Keys page) — not the full tailscale up --auth-key=... command, and not an OAuth client secret.
rivolution_harden_security (default false), independent of
everything else above — installs ufw (allowing Icecast's port, SSH,
and optional external-IP/LAN-subnet allowances), then disables SSH
password authentication, but only if an authorized_keys file already
exists for the install user. If one doesn't exist yet, SSH hardening is
skipped with a warning instead of risking a lockout. Deliberately does
not open the dashboard (rivapi, port 8080) or Stereo Tool's web UI
(port 8079) to the public — Tailscale, above, is the intended way to
reach those remotely.
- Phase 0 — creating the Droplet, or installing a base OS on a UTM VM or physical box. This playbook starts from "fresh Ubuntu/Debian, reachable as root," not before.
- Disk imaging/cloning a literal golden image — this playbook is the replacement for that workflow, not an addition to it. Run it fresh on each target instead of cloning a disk image.
- Per-station configuration inside Rivolution itself (Dropboxes, carts,
schedule codes, RDAdmin host settings, broadcast streams on
/broadcast) — this gets you to a running station with a test tone in the library, not a configured one. - The one remaining manual browser step
postinstitself calls out at the end of every install: opening the dashboard's/patchbaypage and connecting/saving thecaed→ Stereo Tool → stream audio chain. Deliberately left as a real operator action, not scripted around.
Most of this is safe to re-run — it'll just confirm the existing state
and move on (apt itself is the idempotency mechanism for actually
installing Rivolution, both for a downloaded release and a locally
built one). The source method's local build is guarded by its own
marker file instead: once provisioned, the clone/build steps are
skipped entirely on every later run, even if the checkout itself was
deleted or reset in the meantime. If the checkout still exists with
uncommitted local changes when a rebuild is forced, the build role
refuses to touch it rather than silently discarding them.
See the repo's own README for full detail on every variable and the private-repo/deploy-key path.