tech_notes

A collection of notes on setups and implementations.
Log | Files | Refs | README

commit 5e62893d37f0fc012b1b0e4e7d41cc409825f9c3
parent 715e4894982c7f06e7fcb525db74bb43cf1ad57c
Author: Julian Piribauer <julian.piribauer@gmail.com>
Date:   Sat,  2 May 2026 18:28:50 +0000

Add Family Tree installation notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Diffstat:
Afamilytree.md | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+), 0 deletions(-)

diff --git a/familytree.md b/familytree.md @@ -0,0 +1,96 @@ +# Family Tree app + +We document the installation of the self-hosted family tree app running at [familytree.piribauer.ch](https://familytree.piribauer.ch). +The source is available at [git.piribauer.ch/familytree](https://git.piribauer.ch/familytree). + +The app is built with FastAPI and stores its data in a SQLite database. +Authentication is handled entirely by an Authentik outpost via nginx forward-auth; the app reads the `X-Authentik-Username` and `X-Authentik-Email` headers injected by nginx and never touches the Authentik API directly. + +We assume that nginx and an Authentik outpost are already running, and that the repo has been cloned to `/home/julian/familytree`. + +## Python environment + +The system Python on Arch Linux is PEP 668-managed and rejects direct `pip install` calls. +We therefore use a virtual environment: + +```console +$ python -m venv /home/julian/familytree/venv +$ /home/julian/familytree/venv/bin/pip install -r /home/julian/familytree/requirements.txt +``` + +## Database directory + +The app stores its data in a SQLite database under `/var/lib/familytree/`. +We create the directory and assign ownership to the service user: + +```console +# mkdir -p /var/lib/familytree +# chown julian:julian /var/lib/familytree +``` + +## Environment file + +The app reads its configuration from `/home/julian/familytree/.env`. +We create it with the database URL: + +```bash +DATABASE_URL=sqlite:////var/lib/familytree/familytree.db +``` + +## Systemd service + +We install the unit file included in the repo: + +```console +# cp /home/julian/familytree/familytree.service /etc/systemd/system/familytree.service +# systemctl daemon-reload +# systemctl enable --now familytree +``` + +The service runs as user `julian`, listening on `127.0.0.1:8766`. +We can verify it started cleanly with + +```console +$ systemctl status familytree +``` + +## Nginx + +We copy the nginx config from the repo and enable it: + +```console +# cp /home/julian/familytree/nginx/family /etc/nginx/sites-available/family +# ln -s /etc/nginx/sites-available/family /etc/nginx/sites-enabled/family +# nginx -t && systemctl reload nginx +``` + +The config forwards all requests through the Authentik outpost running on `127.0.0.1:9000`. +On success, nginx extracts the username and email from the outpost response and passes them to the app: + +```nginx +auth_request_set $authentik_username $upstream_http_x_authentik_username; +auth_request_set $authentik_email $upstream_http_x_authentik_email; + +proxy_set_header X-Authentik-Username $authentik_username; +proxy_set_header X-Authentik-Email $authentik_email; +``` + +Unauthenticated requests are redirected to the Authentik login page. + +## Schema migrations + +SQLAlchemy creates missing tables on startup with `create_all`, but does not modify tables that already exist. +If a column is added to the models, it must be applied to the existing database manually. +For example, adding a `notes` column to the `persons` table: + +```console +$ sqlite3 /var/lib/familytree/familytree.db "ALTER TABLE persons ADD COLUMN notes TEXT;" +``` + +## Invitation flow + +Users are invited by email address from within the app. +The invitation is stored as a pending record linked to the tree. +When the invited user logs in for the first time, their Authentik email is matched against all pending invitations and the corresponding tree memberships are created automatically. +Trees have three roles: `owner`, `editor`, and `viewer`. +Only owners can invite others or change roles.