6c9cd67a08
Replaces the single shared HTTP Basic service-account credential (which caused a production outage from a username mismatch) with per-user login: Keycloak (already running on this VM for gcnm, now also fronted on auth.friessn.de with its own "homekeeper" realm) authenticates the user once via the landing page, FastAPI verifies the OIDC id_token and mints its own signed session JWT as a cookie, and both Shiny apps forward that per-session token as a Bearer credential instead of a static shared one. Authorization is a simple ALLOWED_USERS allowlist; the old auth.users table and bcrypt seeding are gone entirely. Also carries forward the in-progress rootless Podman/Quadlet migration (gitea, homekeeper, podman roles) and fixes a pre-existing bug where each role's handlers were malformed inside tasks/main.yml instead of their own handlers/main.yml, which broke ansible-playbook entirely. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FbiCdckkTX2HyAkyi1R39d
95 lines
3.4 KiB
Markdown
95 lines
3.4 KiB
Markdown
# Homekeeper Infrastructure
|
|
|
|
Ansible setup for a Hetzner VM (Ubuntu 24.04) running Homekeeper via rootless Podman.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
nginx (system) ← HTTPS
|
|
├── home.friessn.de ← landing page (/var/www/html) + path routing
|
|
│ ├── / → static landing page
|
|
│ ├── /api/ → homekeeper-api on 127.0.0.1:8000
|
|
│ ├── /beekeeper/ → homekeeper-beekeeper on 127.0.0.1:3838
|
|
│ └── /listkeeper/ → homekeeper-listkeeper on 127.0.0.1:3839
|
|
└── git.friessn.de → Gitea on 127.0.0.1:3000 (git + container registry)
|
|
own site file, managed outside this role
|
|
|
|
Podman (rootless, user Quadlets under {{ deploy_user }} → systemd --user units)
|
|
├── homekeeper-db postgres:17, data in named volume {{ homekeeper_db_volume }}
|
|
├── homekeeper-api from Gitea registry, auto-update enabled
|
|
├── homekeeper-beekeeper from Gitea registry, auto-update enabled
|
|
├── homekeeper-listkeeper from Gitea registry, auto-update enabled
|
|
└── gitea from docker.io, data in named volume {{ gitea_data_volume }}
|
|
|
|
All containers run as {{ deploy_user }} (not root) — `loginctl enable-linger`
|
|
keeps the user systemd instance (and its containers) running after logout/reboot.
|
|
```
|
|
|
|
## First-time setup
|
|
|
|
### 1. Provision a Hetzner VM
|
|
- Ubuntu 24.04, min. CX22 (2 vCPU, 4 GB RAM)
|
|
- Add your SSH key in Hetzner console
|
|
- Point your domain DNS A-record to the VM IP
|
|
|
|
### 2. Configure variables
|
|
Edit `group_vars/all.yml`:
|
|
- Set `domain`
|
|
- Set all `CHANGE_ME` passwords (consider `ansible-vault encrypt_string`)
|
|
- Update `inventory/hosts.yml` with the VM IP
|
|
|
|
### 3. First run (without registry login — Gitea not yet up)
|
|
Comment out the "Login to Gitea registry" task in `roles/podman/tasks/main.yml`,
|
|
then run without the homekeeper role:
|
|
|
|
```bash
|
|
ansible-playbook -i inventory/hosts.yml site.yml --skip-tags homekeeper
|
|
```
|
|
|
|
### 4. Set up Gitea
|
|
- Visit https://git.friessn.de/ and complete the installation wizard
|
|
- Create user matching `gitea_admin_user`
|
|
- Create a repository for the code
|
|
- Generate an API token (Settings → Applications) with `package:write` scope
|
|
- Set `registry_token` in `group_vars/all.yml`
|
|
|
|
### 5. Push images to Gitea registry
|
|
On your local machine, build and push the three custom images:
|
|
|
|
```bash
|
|
# Login to Gitea registry
|
|
docker login git.friessn.de -u friessn
|
|
|
|
# Build and push
|
|
docker build -t git.friessn.de/friessn/homekeeper-api:latest ./api
|
|
docker build -t git.friessn.de/friessn/homekeeper-beekeeper:latest ./beekeeper
|
|
docker build -t git.friessn.de/friessn/homekeeper-listkeeper:latest ./listkeeper
|
|
|
|
docker push git.friessn.de/friessn/homekeeper-api:latest
|
|
docker push git.friessn.de/friessn/homekeeper-beekeeper:latest
|
|
docker push git.friessn.de/friessn/homekeeper-listkeeper:latest
|
|
```
|
|
|
|
### 6. Full playbook run
|
|
```bash
|
|
ansible-playbook -i inventory/hosts.yml site.yml
|
|
```
|
|
|
|
## Deploy updates
|
|
|
|
After pushing a new image to the Gitea registry, `podman auto-update` picks it up
|
|
automatically within `autoupdate_schedule` (default: every 15 minutes).
|
|
|
|
For an immediate deploy (containers run rootless as `deploy_user`, not root):
|
|
```bash
|
|
ssh nico@YOUR_IP podman auto-update
|
|
```
|
|
|
|
## Secrets management
|
|
|
|
For production, use ansible-vault:
|
|
```bash
|
|
ansible-vault encrypt_string 'mysecretpassword' --name 'db_password'
|
|
```
|
|
Paste the output into `group_vars/all.yml` and run playbooks with `--ask-vault-pass`.
|