# VNCmail+ on Kubernetes (microk8s) Deploys the VNCmail+ fork as a **new subdomain** (`vncmail.sandbox.vnc.de`), alongside the existing `bulwark.sandbox.vnc.de`. This is Bulwark's native model: a long-lived container + persistent volumes. (Vercel was dropped — its serverless filesystem is read-only, which crashes Bulwark's disk-backed features.) ## Image CI builds and pushes the image on every push to `dev`/`main` (`.github/workflows/docker-publish.yml`): - `dev` → `ghcr.io/brvncde-dotcom/vncmail-plus-dev` - `main` → `ghcr.io/brvncde-dotcom/vncmail-plus-beta` - release tag → `ghcr.io/brvncde-dotcom/vncmail-plus` (clean name) The manifests use the `-dev` image. **For production, pin a digest** instead of `:latest`: ``` kubectl -n vncmail set image deploy/vncmail-plus \ vncmail-plus=ghcr.io/brvncde-dotcom/vncmail-plus-dev@sha256: ``` ## Prerequisites — match your cluster These manifests use microk8s defaults; confirm they match how `bulwark.sandbox.vnc.de` is deployed and edit if not: | Thing | File | Check with | |-------|------|-----------| | StorageClass (`microk8s-hostpath`) | `pvc.yaml` | `kubectl get sc` | | IngressClass (`public`) | `ingress.yaml` | `kubectl get ingressclass` | | cert-manager issuer (`letsencrypt-prod`) | `ingress.yaml` | `kubectl get clusterissuer` + bulwark's ingress | Quickest: copy bulwark's own settings — `kubectl get ingress -A | grep bulwark` then `kubectl get ingress -n -o yaml`. ## Deploy ```bash # 1. Namespace kubectl apply -f namespace.yaml # 2. GHCR pull secret (package is private by default). # Use a GitHub PAT with read:packages. kubectl create secret docker-registry ghcr-pull \ --namespace vncmail \ --docker-server=ghcr.io \ --docker-username=brvncde-dotcom \ --docker-password= \ --docker-email=br@vnc.biz # (Or make the package public in GHCR and remove imagePullSecrets from deployment.yaml.) # 3. App config secret cp secret.example.yaml secret.yaml # edit secret.yaml → set SESSION_SECRET (openssl rand -base64 32) kubectl apply -f secret.yaml # 4. Everything else kubectl apply -k . # kustomization: pvc, deployment, service, ingress # 5. Watch it come up kubectl -n vncmail rollout status deploy/vncmail-plus kubectl -n vncmail get pods,ingress ``` ## DNS Point `vncmail.sandbox.vnc.de` at the same ingress load-balancer IP as `bulwark.sandbox.vnc.de` (A/AAAA or CNAME). cert-manager issues the TLS cert once DNS resolves. ## Verify ```bash curl -sI https://vncmail.sandbox.vnc.de/api/health # expect 200 ``` Then open `https://vncmail.sandbox.vnc.de` and log in with a full `@sandbox.vnc.de` address (e.g. `bernd.rodler@sandbox.vnc.de`) — Stalwart authenticates the **full email**, not a bare username. ## Update after a UI change ```bash git push origin dev # CI rebuilds ghcr.io/...-dev kubectl -n vncmail rollout restart deploy/vncmail-plus # pull new image ``` Promote to production the usual dev-first way (see ../../VNCMAIL-SETUP.md).