The tag manager reads `#LIBREPORTAL|<TAG>|<VALUE>` and takes <VALUE> as the current literal to search for on that line, so it must equal the string in the line body. Mastodon used `unconfigured` as the annotation value against bodies like `PASSWORD_TAG_1_DATA` — nothing matched, nothing was ever substituted, and the placeholder shipped as the live database password, SECRET_KEY_BASE, OTP secret and VAPID keypair. Nothing caught it either: `unconfigured` doesn't match `_DATA`, so tagsManagerGetTagState reported the tags as configured, and the stale-tag gate in dockerComposeUp (which tests the annotation value against `^[A-Z][A-Z0-9_]*_DATA(_[0-9]+)?$`) let the app start. Adopt the convention every other app already uses — body placeholder identical to the annotation value, `<KIND>_DATA_<n>`. All 11 tags now substitute, the app and postgres services agree on the same generated credentials, and an unfilled tag is visible to the pre-start gate. Existing 0.1.0 installs keep their literal credentials until re-installed, and their Postgres was initialised with them, so a plain re-install desynchronises the compose from the volume. Document both recovery paths in upgrade notes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
104 lines
4.0 KiB
Markdown
104 lines
4.0 KiB
Markdown
# LibrePortal — Install & Use
|
|
|
|
How to install, place, update, and remove LibrePortal. For building releases or
|
|
running a dev copy, see [development guide](../contributing/development.md).
|
|
|
|
> **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](../contributing/development.md). The commands below are the intended public flow.
|
|
|
|
## Requirements
|
|
|
|
- A **Debian** or **Ubuntu** host.
|
|
- **root** (run with `sudo`).
|
|
- `curl` (or `wget`) and `tar`.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
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)
|
|
|
|
LibrePortal uses **three independent roots**, each can be its own path/disk:
|
|
|
|
| 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 |
|
|
|
|
```bash
|
|
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 locations are chosen at install and fixed afterward (changing them is a
|
|
deliberate reinstall, not a setting — this is part of the security model).
|
|
|
|
## 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:
|
|
|
|
```bash
|
|
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](upgrade-notes.md) 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
|
|
|
|
```bash
|
|
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.
|