# Grist Deployment This directory contains the Kubernetes manifests for the Grist deployment at https://grist.basicstack.de Grist is an open-source, self-hostable spreadsheet / database hybrid ([grist-core](https://github.com/gristlabs/grist-core)). ## Components - **grist-deployment.yaml**: Main Grist application deployment - Image: `gristlabs/grist:1.7.7` - Port: 8484 - OIDC login via Pocket ID (`https://auth.basicstack.de`) - Data persisted at `/persist` - **grist-service.yaml**: ClusterIP service exposing port 80 -> 8484 - **grist-data-pvc.yaml**: PVC for Grist app data (`/persist`), 20 GiB on `hcloud-volumes-encrypted` - **grist-postgres-deployment.yaml** / **grist-postgres-service.yaml**: In-namespace PostgreSQL 16 for the Grist home database (TypeORM connection) - **grist-db-pvc.yaml**: PVC for PostgreSQL data, 20 GiB on `hcloud-volumes-encrypted` - **grist-ingress.yaml**: Traefik ingress with TLS - Host: `grist.basicstack.de` - TLS via cert-manager (`letsencrypt-prod`, DNS-01 via Hetzner webhook) - **grist-db-credentials-sealed.yaml**: SealedSecret for PostgreSQL user password - **grist-app-secrets-sealed.yaml**: SealedSecret with `GRIST_SESSION_SECRET` - **grist-oidc-secret-sealed.yaml**: SealedSecret with Pocket ID OIDC client credentials ## OIDC Configuration (Pocket ID) - Pocket ID group: `grist` - Client name in Pocket ID: `Grist` - Callback URL: `https://grist.basicstack.de/oauth2/callback` - Client is restricted to members of the `grist` group Grist environment variables driving OIDC (from https://pocket-id.org/docs/client-examples/grist): ``` GRIST_OIDC_IDP_ISSUER=https://auth.basicstack.de GRIST_OIDC_IDP_CLIENT_ID= GRIST_OIDC_IDP_CLIENT_SECRET= GRIST_OIDC_SP_HOST=https://grist.basicstack.de GRIST_OIDC_IDP_SCOPES="openid email profile" GRIST_OIDC_IDP_END_SESSION_ENDPOINT=https://auth.basicstack.de/api/oidc/end-session GRIST_OIDC_SP_IGNORE_EMAIL_VERIFIED=true GRIST_DEFAULT_EMAIL=andreas.leinen@basicstack.de GRIST_FORCE_LOGIN=true ``` `GRIST_DEFAULT_EMAIL` is used by Grist as the primary admin identity - the value must be a valid Pocket ID user. ## Storage Both PVCs (`grist-data`, `grist-db`) use `hcloud-volumes-encrypted` (Retain reclaim policy) as required for sensitive workload data on Hetzner. ## GitOps Managed by Argo CD via `apps/app-grist.yaml`: ```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: grist namespace: argocd spec: project: default source: repoURL: git@forgejo.forgejo.svc.cluster.local:basicstack/stack.basicstack.de.git targetRevision: main path: apps/grist destination: server: https://kubernetes.default.svc namespace: grist syncPolicy: syncOptions: - CreateNamespace=true ``` ## Verification ``` kubectl -n grist get pods kubectl -n grist get pvc kubectl -n grist get ingress curl -I https://grist.basicstack.de ``` ## Backup The PostgreSQL PVC uses reclaim policy `Retain`. For scheduled logical backups add a `CronJob` like the one in `apps/directus/directus-backup-cronjob.yaml`.