LibrePortal/docs/guide/install-and-use.md
librelad 8d41b98497 feat(install): ask where app data goes, like an OS installer
--containers-dir has existed for a while and nobody running the curl|bash
installer ever learned it existed, so a box with a 4 TB disk beside a
small system SSD quietly put everything on the SSD. The installer now
asks, once, in the shape an OS installer asks it.

Deliberately narrow, because a question you answer badly is worse than no
question:

  * app data only. The control plane is ~20 MB and never grows; the thing
    worth placing is the data. Offering all three roots would be three
    questions nobody can answer at that moment.
  * a SUBDIRECTORY on the chosen disk, never its mount point — that keeps
    the "root only ever takes an empty directory" rule intact and leaves
    whatever is already on the disk alone.
  * candidates exclude anything on the same filesystem as /, since placing
    data there gains nothing.

It stays out of the way: skipped when unattended, when --containers-dir
was passed, when there is no TTY, and when the scan finds nothing else —
a prompt with one possible answer is not a question. Self-contained
(findmnt only), since scripts/ is not necessarily loadable that early.

Verified all six paths under a pty: default, valid pick, out-of-range,
non-numeric, no TTY, unattended, explicit flag, and no candidates.

Docs updated: the installer prompt is shown, and the section that said
locations are fixed after install now explains what actually is fixed
(the three roots) versus what isn't (per-app placement, storage add, and
CFG_STORAGE_DEFAULT).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 03:33:44 +01:00

5.1 KiB

LibrePortal — Install & Use

How to install, place, update, and remove LibrePortal. For building releases or running a dev copy, see development guide.

Note: the get.libreportal.org host isn't live yet. Until it is, install from a local release artifact or a git/local checkout — see development guide. The commands below are the intended public flow.

Requirements

  • A Debian or Ubuntu host.
  • root (run with sudo).
  • curl (or wget) and tar.

Install

curl -fsSL https://get.libreportal.org/install.sh | sudo bash

This downloads a versioned, checksum-verified release tarball (no git, no login), installs LibrePortal, and prints the WebUI address + a generated password (also saved to the install log). To choose the password yourself add --password=….

Put data where you want it (separate disks, external drives)

The installer just asks. If it finds a second drive, it offers it for app data before installing anything:

Where should app data live?

  1)  This disk (default)      911.9G   808.4G free
  2)  /mnt/bigdisk             3.6T     3.6T free

  LibrePortal itself stays on this disk either way — only app data moves.

Choose [1]:

It picks a subdirectory on the drive you choose, never the mount point itself, and skips the question entirely when there is nothing else to choose, when you passed --containers-dir, or when running unattended.

The three roots below are still there for scripted installs:

Flag (default) Holds Owner
--system-dir=/libreportal-system configs, database, logs, install the manager user
--containers-dir=/libreportal-containers live app data the container user
--backups-dir=/libreportal-backups backup repositories the container user
curl -fsSL https://get.libreportal.org/install.sh | sudo bash -s -- \
  --system-dir=/mnt/ssd/libreportal \
  --containers-dir=/mnt/ssd/libreportal-apps \
  --backups-dir=/mnt/bigdisk/libreportal-backups

Notes:

  • Defaults are top-level dirs on purpose — they avoid the permission/encryption pitfalls of living inside a user's home. To put containers/backups inside /home/<user> you must add --allow-home (it needs the container user to traverse that home — a small privacy trade-off).
  • Other flags: --manager-user=NAME (default libreportal), --channel=stable|edge (default stable), --version=X.Y.Z (pin a version).

Where things end up

<system-dir>/      configs/  logs/  install/  database.db  ssl/  ssh/
<containers-dir>/  one folder per installed app (+ the libreportal WebUI)
<backups-dir>/     one folder per backup location

The three roots are chosen at install and fixed afterward — changing them is a deliberate reinstall, not a setting, and that is part of the security model.

What is not fixed is where each app's data lives. You can register extra drives at any time and place apps on them individually:

libreportal storage scan             # what else could hold app data
libreportal storage add /mnt/bigdisk # register it (must be an empty directory)
libreportal app move nextcloud bigdisk

New apps follow CFG_STORAGE_DEFAULT (General → Basic), so one setting sends everything to the big disk without touching each app. An app whose drive is not mounted refuses to start rather than being rebuilt empty on the bare mount point.

Update

LibrePortal checks its channel for a newer version and shows a badge in the WebUI when one is available. Apply it from the dashboard, or on the host:

libreportal update apply       # update now if a newer version exists
libreportal update check       # just re-check the channel

Updates download + verify the new release tarball and redeploy. Your data, configs, and backups are untouched (they live outside the replaced install tree).

Some releases carry a fix that an already-installed app only picks up on its next install — see upgrade notes for the versions that need a manual step.

Backups on an external / removable drive

Point a backup location at the drive's mount path. For a removable disk, set Require Mounted Drive on the location (config key CFG_BACKUP_LOC_<n>_REQUIRE_MOUNT=true): LibrePortal then refuses to back up when the drive isn't mounted, so an unplugged disk never silently fills your system disk. Use a Linux filesystem (ext4/xfs/btrfs) — FAT/exFAT/NTFS can't hold the required ownership and will warn.

Uninstall

sudo libreportal-uninstall
# keep the rootless Docker layer + image cache for a fast reinstall:
sudo libreportal-uninstall --skip-docker-images

libreportal-uninstall is a fixed command on $PATH (no data path to type — it reads the real install locations from the installed service, so it works even with custom roots). It removes the three roots, the system users, and the small out-of-tree footprint (/usr/local/lib/libreportal, the /etc integration files).

⚠️ Uninstall permanently deletes all app data, configs, and the database. Take a backup first if you want to keep anything.