# 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`).