Update runbook

Relaunch the kiosk to apply a staged update

When you apply an update from the command line, the new version lands on disk but the mirror keeps running the old one until it relaunches. This runbook activates the staged version over SSH — without rebooting the Pi.

For the normal path — the one-click updater that downloads, verifies, installs and restarts on its own — see Updating. This runbook is for the manual / CLI path, where you are responsible for the relaunch.
On this page

When you need this

You applied an update by hand (or a CLI helper did) and saw a message like:

speculum-apply-update: installed 1.1.0 (service not active — relaunch to apply)

The package is installed, but the on-screen mirror is still the previous version. You want it on the new version now, without waiting for a reboot or physically logging the Pi out and back in.

Why a relaunch is needed

The default kiosk is a desktop-session autostart app, not a systemd service. An XDG autostart entry (installed by speculum-kiosk-enable) launches /opt/speculum/bin/speculum when the desktop session logs in. That entry only fires at login — so a running mirror keeps the old binary in memory until the process is replaced. Installing a new package on disk does not touch the live process.

A JVM process keeps the version it booted with. Updating files on disk has no effect until the process restarts — the screen shows the old build until you relaunch it.

Relaunch without rebooting

This one-liner finds the running mirror, inherits its desktop-session environment, kills it, and respawns the kiosk launcher detached so it survives the SSH disconnect. Run it from your workstation (replace <pi-host> with your Pi's SSH host):

ssh <pi-host> 'P=$(pgrep -f /opt/speculum/bin/speculum | head -1); \
  [ -n "$P" ] && eval "$(tr "\0" "\n" </proc/$P/environ \
    | grep -E "^(DISPLAY|WAYLAND_DISPLAY|XDG_RUNTIME_DIR|DBUS_SESSION_BUS_ADDRESS)=" \
    | sed "s/^/export /")"; \
  kill "$P"; sleep 2; \
  setsid /opt/speculum/libexec/speculum-kiosk-run </dev/null >/dev/null 2>&1 &'

Step by step:

StepWhat it does
pgrep -f …Finds the PID of the running mirror.
tr … /proc/$P/environReads the live process's session environment — DISPLAY, WAYLAND_DISPLAY, XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS — so the new process attaches to the same seat and display. Readable because the SSH user owns the process.
kill "$P"; sleep 2Stops the old mirror and gives it a moment to release port 8080.
setsid … &Launches speculum-kiosk-run in a new session, detached from SSH, so it keeps running after you log out.
Run it interactively. Non-interactive / BatchMode SSH may be refused (publickey/password). Run from a real terminal where you can authenticate.

Verify it took

Confirm the mirror is running again on the new binary:

ssh <pi-host> 'pgrep -a -f /opt/speculum/bin/speculum'

You should see one process. The mirror on screen — and the version badge in the web admin header — should now show the new release.

Reboot fallback

If the one-liner reports no PID (nobody is logged into the desktop session, so there's no session environment to inherit), just reboot — autostart relaunches the mirror fresh on the new version at login:

ssh -t <pi-host> 'sudo systemctl reboot'

Logging the desktop session out and back in works too — it's the same code path the autostart entry uses.

If it doesn't work

← Updating Troubleshooting →