Pi: minimal self-contained compose project (D-125)

The Kvitt Pi runs Kvitt from /home/jacobhagstedt/kvitt: compose.yaml, .env,
secrets/ and relative bind mounts ./data, ./backups, ./import. Both containers
run as the owner's uid/gid (KVITT_UID, KVITT_GID). No install script, no /opt,
no Docker daemon or system changes; operations are plain docker compose
commands (README "Pi: what the owner does", RESTORE.md).

Removed install.sh, deploy.sh, bootstrap.sh, backup-now.sh, install-apk.sh,
lib.sh. .env holds only the keys compose.yaml reads; RCLONE_REMOTE is fixed
to gdrive: in compose.yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-20 19:18:53 +02:00
parent 200c99f2f6
commit 6e5981d62a
12 changed files with 225 additions and 663 deletions
+14 -29
View File
@@ -1,32 +1,17 @@
# Kvitt Pi settings (SPEC §10.2). Copy to .env in this folder, replace every CHANGE_ME, then run ./install.sh,
# which copies it to /opt/kvitt/.env (mode 0600). install.sh refuses a CHANGE_ME left in a key it checks.
# No secret files here: those go to /opt/kvitt/secrets/ (infra/README.md "Pi: what the owner does").
# Kvitt on the Kvitt Pi (SPEC §10.2, D-125). Copy to .env next to compose.yaml and set HA_HOST; check KVITT_UID and
# KVITT_GID against `id -u` and `id -g` on the Pi. Every key is read by compose.yaml and by nothing else.
# --- Read by compose.yaml -----------------------------------------------------------------------------------------
# Registry and owner path of the Kvitt images; images are ${KVITT_REGISTRY}/kvitt-server|kvitt-backup.
# compose.yaml: image names ${KVITT_REGISTRY}/kvitt-server and /kvitt-backup (D-104).
KVITT_REGISTRY=gitea.lan/jacobh2
# Image tag to run. deploy.sh sets it; first install: the newest version tag the Gitea workflow pushed (vMAJOR.MINOR.PATCH),
# or the short git SHA that infra/build-images.sh printed.
KVITT_TAG=CHANGE_ME_TAG
# Kvitt's own public host name (D-120), owner-chosen: a domain or DuckDNS name pointing at the home's public address.
# NPM holds its Let's Encrypt certificate and serves it on the default HTTPS port 443, which the router already
# forwards to NPM for Home Assistant (D-124). Invite links and the landing page use https://<KVITT_PUBLIC_HOST>
# (KVITT_PUBLIC_URL, no port). Not icehack.asuscomm.com: that name is NPM's proxy host for Home Assistant.
KVITT_PUBLIC_HOST=CHANGE_ME_KVITT_PUBLIC_HOST
# LAN IPv4 address of the Home Assistant Pi, where Nginx Proxy Manager terminates TLS and forwards to this Pi's port
# 8080 (D-120). The server trusts X-Forwarded-For only from this address (KVITT_TRUSTED_PROXY), so it must be the
# address NPM's connections come from: an IP literal such as 192.168.1.20, not a host name (install.sh checks it).
# Kept the name HA_HOST (the proxy host); it no longer has the SSH settings HA_PORT, HA_USER, HA_CERT_DIR of cert-sync.
HA_HOST=CHANGE_ME_HA_HOST
# rclone remote of the Drive backups, as named in rclone.conf.
RCLONE_REMOTE=gdrive:
# Google Drive folder id the backups go to (OQ-4, answered).
# compose.yaml: image tag of both services; deploy or roll back = change it, then pull and up -d.
KVITT_TAG=v1.0.0
# compose.yaml: the server's KVITT_PUBLIC_URL=https://<this>, used in invite links and the landing page (D-124).
KVITT_PUBLIC_HOST=kvitt.suorra.duckdns.org
# compose.yaml: the server's KVITT_TRUSTED_PROXY, the Home Assistant Pi's (NPM's) LAN IPv4 address, e.g. 192.168.1.20.
HA_HOST=CHANGE_ME
# compose.yaml: uid both containers run as, `id -u` of the user that owns ~/kvitt on the Pi.
KVITT_UID=1000
# compose.yaml: gid both containers run as, `id -g` of the same user.
KVITT_GID=1000
# compose.yaml: the backup's Google Drive folder id (OQ-4).
RCLONE_FOLDER_ID=1jDp1dGE5R3H2DBcXCqIPN1iWzQnPkdlV
# --- Read by install.sh only (never by the containers) ------------------------------------------------------------
# Gitea user that may pull the images; leave empty when the Gitea packages are public (anonymous pull).
KVITT_REGISTRY_USER=
# Gitea access token of that user with read:package scope; leave empty for anonymous pull. Never commit a filled .env.
KVITT_REGISTRY_TOKEN=