docs(ops): document registry secrets, rollback, Gitea runner image

operations.md lists the full secret/variable matrix the deploy workflow
expects, the new compose.yaml + compose.netcup.yaml invocation, and a
note on why both workflow jobs pin catthehacker/ubuntu:runner-latest.
self-hosting.md updates the example LIBRENOTES_IMAGE value to the Gitea
Packages path and switches the quick-start to compose.netcup.yaml.
This commit is contained in:
2026-04-29 02:00:29 +02:00
parent 51fb2fe636
commit 2784e0fa7c
2 changed files with 48 additions and 20 deletions
+37 -15
View File
@@ -21,26 +21,32 @@ The workflow expects these secrets and variables on the repo:
| Name | Type | Purpose |
| ---- | ---- | ------- |
| `REGISTRY` | secret | hostname of the OCI registry |
| `REGISTRY_USER` | secret | robot account |
| `REGISTRY_PASS` | secret | robot token |
| `DEPLOY_HOST` | secret | `user@host` SSH target |
| `DEPLOY_KEY` | secret | passphrase-less private key |
| `DEPLOY_PATH` | secret | absolute path on host with `docker-compose.*.yml` |
| `HEALTH_URL` | secret | e.g. `https://librenot.es/healthz` |
| `REGISTRY` | secret | registry hostname, e.g. `git.librete.ch` |
| `REGISTRY_USER` | secret | robot account or PAT username with `package:write` |
| `REGISTRY_PASS` | secret | robot/PAT token |
| `DEPLOY_HOST` | secret | `user@host` SSH target, e.g. `root@netcup` |
| `DEPLOY_KEY` | secret | passphrase-less private key (PEM) |
| `DEPLOY_PATH` | secret | absolute path on host with the compose stack, e.g. `/srv/librenotes` |
| `HEALTH_URL` | secret | e.g. `https://ln.cloud.librete.ch/healthz` |
| `DEPLOY_ENABLED` | variable | `true` to enable the workflow |
The image is pushed to `${REGISTRY}/public/librenotes`; main pushes
publish `:main` and `:<sha7>`, tag pushes publish `:vX.Y.Z` and
`:latest`.
### Production compose stack
On the deployment host, place `docker-compose.yml` and
`docker-compose.prod.yml` from this repo at `$DEPLOY_PATH`,
together with an `.env` file containing the runtime configuration
(JWT secret, SMTP credentials, public base URL, image tag).
On the deployment host, place `compose.yaml` and
`compose.netcup.yaml` from this repo at `$DEPLOY_PATH`, together
with an `.env` file containing `LIBRENOTES_IMAGE` plus the runtime
configuration (JWT secret, SMTP credentials, public base URL).
See `.env.netcup.example` for the full key list.
Bring it up with:
```sh
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker compose -f compose.yaml -f compose.netcup.yaml pull
docker compose -f compose.yaml -f compose.netcup.yaml up -d
```
### Rollback
@@ -52,11 +58,27 @@ on health-check failure — failed health alerts the operator via
the workflow itself, who can then redeploy the prior tag manually.
```sh
# Example: roll back to v0.1.2
sed -i 's/^LIBRENOTES_IMAGE=.*/LIBRENOTES_IMAGE=registry.librete.ch\/librenotes:v0.1.2/' .env
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Example: roll back to v0.1.0
perl -i -pe 's|^LIBRENOTES_IMAGE=.*|LIBRENOTES_IMAGE=git.librete.ch/public/librenotes:v0.1.0|' .env
docker compose -f compose.yaml -f compose.netcup.yaml pull
docker compose -f compose.yaml -f compose.netcup.yaml up -d
```
### Gitea Actions runner
Workflows run on the netcup `act_runner` (see `runner/` stack in
the netcup umbrella). Both jobs declare `container: catthehacker/ubuntu:runner-latest`
because:
- The default runner label image (`node:20-bookworm`) lacks `make`
and `docker`, both required by the workflows.
- The `runner-latest` image bundles `make`, `git`, `curl`, `ssh`,
`node`, plus a docker CLI.
The runner config (`runner/config.yaml`) declares
`/var/run/docker.sock` as a `valid_volume` so the build job can
mount the host socket and push images via `docker/build-push-action`.
## Backups
`scripts/backup.sh` is a self-contained backup driver suitable for
+11 -5
View File
@@ -23,10 +23,16 @@ Docker Compose. For day-2 ops (deploys, backups) see
```sh
git clone https://git.librete.ch/public/librenotes
cd librenotes
cp .env.example .env # edit values, see below
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
cp .env.netcup.example .env # edit values, see below
docker compose -f compose.yaml -f compose.netcup.yaml pull
docker compose -f compose.yaml -f compose.netcup.yaml up -d
```
The `compose.netcup.yaml` overlay is the production-style overlay
shipped in this repo; it pulls a published image, drops host port
binding (assumes a fronting reverse proxy), and joins an external
`edge` docker network. Adapt to your topology if needed.
Visit `https://your-domain/` and sign in.
## Environment configuration
@@ -45,7 +51,7 @@ Place them in an `.env` file next to the Compose stack.
| `LIBRENOTES_SMTP_FROM` | yes | Envelope sender, e.g. `no-reply@notes.example.com`. |
| `LIBRENOTES_DATA_DIR` | no | Default `/data` inside the container. |
| `LIBRENOTES_DB` | no | Default `/var/lib/librenotes/librenotes.db`. |
| `LIBRENOTES_IMAGE` | yes (prod) | Image tag to pull, e.g. `registry.librete.ch/librenotes:v0.1.0`. |
| `LIBRENOTES_IMAGE` | yes (prod) | Image tag to pull, e.g. `git.librete.ch/public/librenotes:v0.1.0`. |
Generate a JWT secret:
@@ -109,8 +115,8 @@ to use `curl`/`wget`).
Pull the new image and restart:
```sh
docker compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker compose -f compose.yaml -f compose.netcup.yaml pull
docker compose -f compose.yaml -f compose.netcup.yaml up -d
```
To pin a specific version, set `LIBRENOTES_IMAGE` to that tag in