Merge claude/1
This commit is contained in:
commit
846936617e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -4,6 +4,7 @@
|
|||||||
scripts/unused export-ignore
|
scripts/unused export-ignore
|
||||||
scripts/release export-ignore
|
scripts/release export-ignore
|
||||||
site export-ignore
|
site export-ignore
|
||||||
|
docs export-ignore
|
||||||
.claude export-ignore
|
.claude export-ignore
|
||||||
.gitignore export-ignore
|
.gitignore export-ignore
|
||||||
.gitattributes export-ignore
|
.gitattributes export-ignore
|
||||||
|
|||||||
17
README.md
17
README.md
@ -34,11 +34,22 @@ telemetry. See [our Promise](PROMISE.md) for exactly what that means.
|
|||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://gitea.scottwebstar.co.uk/Webstar/LibrePortal.git
|
curl -fsSL https://get.libreportal.org/install.sh | sudo bash
|
||||||
cd LibrePortal
|
|
||||||
./init.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This installs a versioned, checksum-verified release (Debian/Ubuntu, root). Put
|
||||||
|
data on separate disks with `--system-dir=` / `--containers-dir=` / `--backups-dir=`.
|
||||||
|
|
||||||
|
> The `get.libreportal.org` host is still being set up — until it's live, build a
|
||||||
|
> release and install from it locally (see the docs below).
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- **[docs/USER.md](docs/USER.md)** — install, place data on separate disks/drives,
|
||||||
|
update, back up, uninstall.
|
||||||
|
- **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)** — run a dev copy, cut stable/edge
|
||||||
|
releases, and test them before publishing.
|
||||||
|
|
||||||
## LibrePortal Connect (optional)
|
## LibrePortal Connect (optional)
|
||||||
|
|
||||||
Self-hosting is free and complete. If you'd rather not fiddle with the tricky
|
Self-hosting is free and complete. If you'd rather not fiddle with the tricky
|
||||||
|
|||||||
128
docs/DEVELOPMENT.md
Normal file
128
docs/DEVELOPMENT.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# LibrePortal — Development & Releases
|
||||||
|
|
||||||
|
How to run a development copy, cut stable/edge releases, and test them before they
|
||||||
|
go out. For installing/using LibrePortal, see [USER.md](USER.md).
|
||||||
|
|
||||||
|
## Mental model (read this first)
|
||||||
|
|
||||||
|
**Install modes** — `CFG_INSTALL_MODE` decides where the code comes from:
|
||||||
|
|
||||||
|
| Mode | Source | Use |
|
||||||
|
|---|---|---|
|
||||||
|
| `release` (default) | a checksum-verified `.tar.gz` over HTTPS | end users / stable |
|
||||||
|
| `git` | `git clone` of the repo | contributors tracking a branch |
|
||||||
|
| `local` | a copy of a local folder | hacking on the code on the box |
|
||||||
|
|
||||||
|
**Three roots** (each relocatable at install, then fixed):
|
||||||
|
`<system>` (manager-owned: configs/db/logs/install) · `<containers>` (container
|
||||||
|
user: app data) · `<backups>` (container user: repos). Defaults `/libreportal-*`.
|
||||||
|
|
||||||
|
**Two users:** the **manager** (`sudo_user_name`, default `libreportal`) owns the
|
||||||
|
control plane and runs the runtime; the **container user** (`CFG_DOCKER_INSTALL_USER`,
|
||||||
|
default `dockerinstall`) owns app data + runs rootless Docker. Genuine-root actions
|
||||||
|
go through fixed, root-owned helpers in `/usr/local/lib/libreportal/` (paths +
|
||||||
|
manager name are *baked* into them at install — never read from runtime config).
|
||||||
|
|
||||||
|
**Key files:**
|
||||||
|
- `init.sh` — the installer (self-contained; creates users/folders/helpers, bakes things).
|
||||||
|
- `install.sh` — the thin bootstrap (download+verify+extract a release, then run init.sh).
|
||||||
|
- `scripts/source/paths.sh` — resolves the three roots + manager user.
|
||||||
|
- `scripts/source/fetch.sh` — `lpFetchRelease` / `lpVersionGt` (runtime fetch + version compare).
|
||||||
|
- `scripts/release/make_release.sh` — builds release artifacts.
|
||||||
|
- `VERSION` — the single source of the version number.
|
||||||
|
|
||||||
|
## Run a development copy
|
||||||
|
|
||||||
|
From a clone of the repo, on a **throwaway Debian/Ubuntu host** (install is
|
||||||
|
destructive — it creates system users and dirs):
|
||||||
|
|
||||||
|
**Local mode** (install from the working tree — best for hacking):
|
||||||
|
```bash
|
||||||
|
sudo ./init.sh --random-password --local init
|
||||||
|
# custom locations work in dev too:
|
||||||
|
sudo ./init.sh --random-password --local --system-dir=/srv/lp --manager-user=lpadmin init
|
||||||
|
```
|
||||||
|
|
||||||
|
**Git mode** (track a branch):
|
||||||
|
```bash
|
||||||
|
# via the bootstrap:
|
||||||
|
sudo ./install.sh --git-url=https://example.com/you/LibrePortal.git \
|
||||||
|
--git-user=USER --git-token=TOKEN
|
||||||
|
# or directly: ./init.sh init <password> <git_user> <git_token> <git_url> true git
|
||||||
|
```
|
||||||
|
|
||||||
|
**Iterating:** re-run the installer to redeploy after changes (local mode re-copies
|
||||||
|
the tree). To wipe and start over:
|
||||||
|
```bash
|
||||||
|
sudo ./init.sh uninstall # removes the three roots + users + footprint
|
||||||
|
sudo ./init.sh --skip-docker-images uninstall # keep the Docker layer for a fast reinstall
|
||||||
|
```
|
||||||
|
|
||||||
|
> This repo's CI/hook setup may auto-deploy on commit (commit on a branch →
|
||||||
|
> auto-merge → redeploy). That's environment-specific; the commands above are the
|
||||||
|
> portable way to stand up and refresh a dev box.
|
||||||
|
|
||||||
|
## Cut a release (stable or edge)
|
||||||
|
|
||||||
|
1. **Bump the version** in `VERSION` (semver, e.g. `0.2.0` → `0.3.0`). Commit it.
|
||||||
|
2. **Build the artifact** (uses `git archive`, so it ships only committed files and
|
||||||
|
honours `.gitattributes export-ignore` — `scripts/unused`, `site`, `docs`,
|
||||||
|
`.claude`, the release tooling, etc. never ship):
|
||||||
|
```bash
|
||||||
|
scripts/release/make_release.sh stable # or: edge [git-ref]
|
||||||
|
```
|
||||||
|
Produces, under `dist/<channel>/`:
|
||||||
|
- `libreportal-<version>.tar.gz` — the release
|
||||||
|
- `libreportal-<version>.tar.gz.sha256` — its checksum
|
||||||
|
- `latest.json` — `{ version, channel, url, sha256, notes }` (the channel pointer)
|
||||||
|
3. **Publish** by copying `dist/<channel>/*` to the host so they're served at
|
||||||
|
`https://get.libreportal.org/<channel>/…` (Phase E — the `getlibreportal`
|
||||||
|
container; not built yet). `latest.json` is what makes a version "the latest".
|
||||||
|
|
||||||
|
**Channels:** `stable` is the default users get; `edge` is for early/testing
|
||||||
|
builds. Same tooling, different `<channel>`. To promote an edge build to stable,
|
||||||
|
rebuild with `make_release.sh stable` at that ref (or copy its artifacts into the
|
||||||
|
`stable/` path and update `stable/latest.json`).
|
||||||
|
|
||||||
|
## Test a release locally before publishing
|
||||||
|
|
||||||
|
No hosting needed — serve `dist/` and point an install at it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# build, then serve the artifacts
|
||||||
|
scripts/release/make_release.sh stable
|
||||||
|
( cd dist && python3 -m http.server 8000 )
|
||||||
|
|
||||||
|
# on a throwaway host, install from your local server:
|
||||||
|
LP_RELEASE_BASE_URL=http://<your-ip>:8000 \
|
||||||
|
sudo ./install.sh --channel=stable --system-dir=/libreportal-system
|
||||||
|
```
|
||||||
|
|
||||||
|
`LP_RELEASE_BASE_URL` overrides the release host everywhere (installer, updater,
|
||||||
|
recovery). Quick non-destructive checks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# fetch + verify + stage only (no install):
|
||||||
|
LP_RELEASE_BASE_URL=http://<ip>:8000 ./install.sh --dry-run
|
||||||
|
# tamper with the tarball and confirm it's refused:
|
||||||
|
echo x >> dist/stable/libreportal-*.tar.gz
|
||||||
|
LP_RELEASE_BASE_URL=http://<ip>:8000 ./install.sh --dry-run # => CHECKSUM MISMATCH
|
||||||
|
```
|
||||||
|
|
||||||
|
## How updates work (so you can reason about them)
|
||||||
|
|
||||||
|
In `release` mode the WebUI badge + `libreportal update apply` compare the local
|
||||||
|
`VERSION` against the channel's `latest.json` (`lpVersionGt`); if newer, they
|
||||||
|
`lpFetchRelease` the new tarball (verified) and redeploy. Because the install tree
|
||||||
|
is *code only* (configs/logs/backups live in the other roots), the update just
|
||||||
|
replaces it — no backup/restore dance. `git`/`local` modes keep their existing
|
||||||
|
git-based update path.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- **Versioning:** semver in `VERSION`. Bump before building; `latest.json` carries it.
|
||||||
|
- **New runtime script?** Add it under `scripts/<area>/…` and run
|
||||||
|
`scripts/source/files/generate_arrays.sh run` so it's sourced (build/standalone
|
||||||
|
tooling under `scripts/release` and `scripts/system` is intentionally excluded).
|
||||||
|
- **Don't** make the OS footprint (`/etc/*`, `/usr/local/*`) relocatable — it's
|
||||||
|
fixed by design for the privilege model.
|
||||||
97
docs/USER.md
Normal file
97
docs/USER.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# LibrePortal — Install & Use
|
||||||
|
|
||||||
|
How to install, place, update, and remove LibrePortal. For building releases or
|
||||||
|
running a dev copy, see [DEVELOPMENT.md](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.md](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).
|
||||||
|
|
||||||
|
## 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-system/install/init.sh uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
This removes the three roots, the system users, and the small out-of-tree
|
||||||
|
footprint (`/usr/local/lib/libreportal`, the `/etc` integration files). Add
|
||||||
|
`--skip-docker-images` to keep the rootless Docker layer + image cache for a fast
|
||||||
|
reinstall.
|
||||||
|
|
||||||
|
> ⚠️ Uninstall permanently deletes all app data, configs, and the database. Take a
|
||||||
|
> backup first if you want to keep anything.
|
||||||
Loading…
x
Reference in New Issue
Block a user