stack.basicstack.de/apps/kaneo/README.md
CTO bf7e78a573 feat(kaneo): wire SMTP submission via kaneo@basicstack.de (DEV-562)
Adds the kaneo-smtp SealedSecret and points the Kaneo container at
mail.basicstack.de:587 (STARTTLS) for outbound workspace invites and
notifications. DISABLE_EMAIL_OTP_SIGN_IN stays true so sign-in remains
OIDC-only via Pocket ID.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-05 10:01:52 +00:00

61 lines
2.8 KiB
Markdown

# Kaneo
Self-hosted [Kaneo](https://github.com/usekaneo/kaneo) — open-source project
management — deployed on the BasicStack Kubernetes cluster.
- **URL:** https://kaneo.basicstack.de
- **Namespace:** `kaneo`
- **Distribution:** hand-rolled manifests, GitOps-managed by Argo CD
(see `apps/app-kaneo.yaml`).
- **Auth:** OIDC via Pocket ID (`https://auth.basicstack.de`) with
`CUSTOM_OAUTH_*` env vars. Client id + secret live in
`kaneo-oidc-secret` (SealedSecret). Access is restricted to
Pocket ID groups `kaneo-admins` / `kaneo-members`.
- **Database:** dedicated PostgreSQL in-namespace on
`hcloud-volumes-encrypted` (20Gi). Both the Postgres and Kaneo
pods pin to the `fsn1` datacenter via
`csi.hetzner.cloud/location=fsn1` node affinity — the Hetzner
volume is DC-local.
- **TLS:** Traefik ingress, cert issued by `letsencrypt-prod`
(DNS-01 via the Hetzner cert-manager webhook).
- **Image:** `ghcr.io/usekaneo/kaneo:2.22.0` (single container
bundling API + web on port 5173, health at `/api/health`).
## Files
| File | Purpose |
| --- | --- |
| `kaneo-postgres-pvc.yaml` | 20 Gi encrypted Hetzner volume for Postgres data. |
| `kaneo-postgres-deployment.yaml` | Postgres 16-alpine, pinned to `fsn1`. |
| `kaneo-postgres-service.yaml` | ClusterIP service `kaneo-postgres:5432`. |
| `kaneo-db-credentials-sealed.yaml` | Postgres user password (SealedSecret). |
| `kaneo-app-secrets-sealed.yaml` | `AUTH_SECRET` (Better Auth JWT secret, ≥32 chars). |
| `kaneo-oidc-secret-sealed.yaml` | OIDC client id + secret from Pocket ID. |
| `kaneo-smtp-sealed.yaml` | SMTP submission credentials for `kaneo@basicstack.de` (SealedSecret). |
| `kaneo-deployment.yaml` | Kaneo app deployment (pinned to `fsn1`). |
| `kaneo-service.yaml` | ClusterIP service on port 80 → container 5173. |
| `kaneo-ingress.yaml` | Traefik ingress + `letsencrypt-prod` cert. |
## Post-deploy setup
1. Point browser at https://kaneo.basicstack.de and sign in via the
"Sign in with Pocket ID" (custom OAuth) button.
2. The first admin (`andreas.leinen@basicstack.de`, member of
`kaneo-admins`) must be promoted inside Kaneo — the current
upstream release does not map OIDC groups to roles.
## SMTP
Outbound SMTP is wired to the Stalwart submission relay at
`mail.basicstack.de:587` (STARTTLS) using the `kaneo@basicstack.de`
mailbox. Credentials live in the `kaneo-smtp` SealedSecret
(`kaneo-smtp-sealed.yaml`) with keys `smtp-user` and `smtp-password`.
SMTP is used only for workspace invites and notifications;
`DISABLE_EMAIL_OTP_SIGN_IN=true` remains set so users still sign in via
Pocket ID SSO, not email codes.
To rotate the mailbox password: update it in Stalwart, re-seal
`kaneo-smtp` with the new value, commit, and let Argo apply. The
existing pod picks up the new secret on next restart
(`kubectl -n kaneo rollout restart deploy/kaneo`).