# 🚀 Element Server Suite (ESS) Community – GitOps Deployment Guide Dieses Repository enthĂ€lt die Infrastruktur-as-Code (IaC) fĂŒr den Matrix-Homeserver (basierend auf der Element Server Suite Community Edition), der per **FluxCD** nach GitOps-Prinzipien verwaltet wird. ## 📑 Inhaltsverzeichnis 1. [Voraussetzungen & Lokale Tools](https://www.google.com/search?q=%231-voraussetzungen--lokale-tools) 2. [Architektur & Logik des Stacks](https://www.google.com/search?q=%232-architektur--logik-des-stacks) 3. [Aufbau des Repositories](https://www.google.com/search?q=%233-aufbau-des-repositories) 4. [Das Deployment (Aktueller Stand)](https://www.google.com/search?q=%234-das-deployment-aktueller-stand) 5. [NĂŒtzliche Befehle](https://www.google.com/search?q=%235-n%C3%BCtzliche-befehle) 6. [Troubleshooting & Known Issues](https://www.google.com/search?q=%236-troubleshooting--known-issues) ----- ## 1\. Voraussetzungen & Lokale Tools Um mit diesem Stack zu interagieren (Konfigurationen anzupassen, Secrets zu verschlĂŒsseln, Fehler zu suchen), mĂŒssen folgende Tools lokal installiert sein: ### đŸ› ïž Benötigte CLI-Tools * **`kubectl`**: FĂŒr die direkte Kommunikation mit dem Kubernetes-Cluster. * **`flux`**: FĂŒr das manuelle Anstoßen von GitOps-Synchronisationen. * **`sops`** & **`age`** (oder GPG): FĂŒr die Ver- und EntschlĂŒsselung von Secrets direkt im Git-Repo. * **`helm`**: (Optional) Zum Inspizieren von Chart-Values. ### 🍏 macOS (via Homebrew) ```bash brew install kubectl fluxcd/tap/flux sops age helm ``` ### 🐧 Linux ```bash # kubectl & helm via Paketmanager (apt/dnf) oder curl curl -sLS https://fluxcd.io/install.sh | sudo bash # SOPS wget https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 sudo mv sops-v3.8.1.linux.amd64 /usr/local/bin/sops && sudo chmod +x /usr/local/bin/sops sudo apt install age ``` ### đŸȘŸ Windows (via Winget oder WSL2) *Empfehlung: Nutze WSL2 (Ubuntu) und folge den Linux-Schritten.* Nativ via Winget: ```powershell winget install Kubernetes.kubectl FluxCD.Flux Mozilla.sops age-encryption.age Helm.Helm ``` ### ⚙ Lokale Konfiguration 1. **Kubeconfig:** Stelle sicher, dass die Datei `~/.kube/config` mit den Zugangsdaten zu deinem K3s-Cluster gefĂŒllt ist. Test: `kubectl get nodes`. 2. **SOPS Key:** Du benötigst den privaten `age`-Key (oder GPG-Key), der in der `.sops.yaml` des Repositories hinterlegt ist, um Secrets bearbeiten zu können. 3. **Git Hooks installieren:** Nach dem Klonen dieses Repositories mĂŒssen Git Hooks installiert werden, um ConfigMap-Änderungen automatisch zu tracken: ```bash cd prod/gitops ./scripts/install-hooks.sh ``` Siehe [📖 GitOps ConfigMap Auto-Sync](docs/ops-configmap-sync.md) fĂŒr Details. ----- ## 2\. Architektur & Logik des Stacks Das Setup basiert auf einer modernen, modularen GitOps-Architektur: ### Management-Komponenten * **K3s**: Die leichtgewichtige Kubernetes-Distribution, die als Fundament dient. * **FluxCD**: Der GitOps-Controller. Er ĂŒberwacht dieses Git-Repository. Ändert sich hier eine Datei, wendet Flux die Änderung automatisch im Cluster an. * **SOPS**: Erlaubt es, Passwörter (z.B. SMTP) verschlĂŒsselt in Git zu speichern. Flux entschlĂŒsselt diese "on the fly" im Cluster. * **Traefik**: Der Ingress-Controller (Standard bei K3s). Er leitet Traffic von Port 80/443 an die richtigen internen Pods weiter. * **Cert-Manager**: Spricht mit Let's Encrypt und stellt automatisch gĂŒltige TLS-Zertifikate fĂŒr alle Ingress-Routen aus. ### Matrix Stack (ESS Community v26.4.0) Die Suite ist ein "Umbrella Chart", das aus mehreren Microservices besteht: * **Synapse (`matrix.`):** Das eigentliche Backend (Homeserver) fĂŒr die Chat-Nachrichten. * **Matrix Authentication Service (MAS) (`account.`):** Der OIDC-basierte Login-Server. Zwingend erforderlich fĂŒr moderne Matrix-Clients. * **Element Web (`domain.tld`):** Der Web-Client fĂŒr die Endnutzer. * **Matrix RTC (`mrtc.`):** Die SFU (Selective Forwarding Unit) fĂŒr Audio-/Video-Calls. * **PostgreSQL:** Die relationale Datenbank fĂŒr Synapse und MAS. ----- ## 3\. Aufbau des Repositories Das Repository ist strikt nach "Infrastruktur" und "Applikation" getrennt, um AbhĂ€ngigkeiten korrekt zu laden. ```text gitops/ ├── .sops.yaml # Definiert, wie Secrets verschlĂŒsselt werden ├── clusters/matrix/ # Der Einstiegspunkt fĂŒr FluxCD ├── apps/ │ ├── base/ │ │ ├── infra/ # Core-Dienste (Cert-Manager, Namespaces) │ │ └── matrix/ # Die OCI Helm-Repository Definition fĂŒr ESS │ └── production/ # Das eigentliche Matrix-Deployment │ ├── kustomization.yaml # Inhaltsverzeichnis │ ├── element-server-suite.yaml # Das HelmRelease (Bestellung an Flux) │ ├── cert-issuer.yaml # Let's Encrypt Konfiguration │ ├── matrix-postgres-auth.yaml # DB-Passwörter │ └── custom-configs/ # Eigene Anpassungen (Themes, Logging) │ ├── synapse-values.yaml # Als ConfigMap │ ├── element-values.yaml # Als ConfigMap │ └── mas-secrets.sops.yaml # Als verschlĂŒsseltes SOPS-Secret ``` **AbhĂ€ngigkeits-Logik:** Flux installiert erst `infra-apps` (damit Namespaces und Repositories existieren) und danach `production-apps` (das eigentliche ESS-Chart). ----- ## 4\. Das Deployment (Aktueller Stand) ### Das HelmRepository (OCI) Element verteilt die Community-Edition modern ĂŒber die GitHub Container Registry (`ghcr.io`). Klassische HTTP-Helm-Repos werfen hier oft 404-Fehler. ```yaml # apps/base/matrix/ess-repo.yaml apiVersion: source.toolkit.fluxcd.io/v1 kind: HelmRepository metadata: name: element-ess-oci spec: type: oci url: oci://ghcr.io/element-hq/ess-helm ``` ### Das HelmRelease (Das HerzstĂŒck) Das ESS-Chart (`v26.4.0`) hat ein extrem striktes JSON-Schema. Konfigurationen mĂŒssen exakt sitzen: * `serverName` muss an der Wurzel stehen. * Komponenten werden in `camelCase` geschrieben (`elementWeb`, `synapseAdmin`). * Zertifikate werden durch `certManager: true` automatisch gemanaged. **Keine manuellen TLS-EintrĂ€ge im Ingress-Block\!** ```yaml # apps/production/element-server-suite.yaml (Auszug) apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: matrix-stack spec: chart: spec: chart: matrix-stack version: "26.4.0" valuesFrom: - kind: ConfigMap name: ess-synapse-custom valuesKey: values.yaml - kind: Secret name: ess-mas-custom-secrets valuesKey: values.yaml values: serverName: axion1337.chat certManager: true postgres: enabled: true synapse: enabled: true ingress: { host: matrix.axion1337.chat } matrixAuthenticationService: enabled: true ingress: { host: account.axion1337.chat } elementWeb: enabled: true ingress: { host: axion1337.chat } wellKnownDelegation: enabled: false # ! WICHTIG (Siehe Troubleshooting) ``` ----- ## 5\. NĂŒtzliche Befehle ### 🔄 Flux / GitOps Sync erzwingen Wenn man nicht auf den automatischen 10-Minuten-Timer von Flux warten will: ```bash flux reconcile kustomization flux-system --with-source flux reconcile kustomization production-apps --with-source ``` ### 🔍 Status des Deployments prĂŒfen ```bash # Zeigt, ob Flux das Chart akzeptiert und angewendet hat flux get helmreleases -A # Zeigt an, ob die Pods erfolgreich starten kubectl get pods -n matrix ``` ### 🔐 Zertifikate (Let's Encrypt) debuggen ```bash # Sind die Zertifikate da und gĂŒltig? kubectl get certificate -n matrix # Wo hĂ€ngt der Request? (403 Fehler etc.) kubectl get certificaterequest -n matrix kubectl get challenges -n matrix kubectl describe challenge -n matrix ``` ### đŸ›Ąïž Secrets mit SOPS bearbeiten Um ein Passwort im GitOps-Repo zu Ă€ndern, editiert man die verschlĂŒsselte Datei direkt via SOPS (sie wird transparent entschlĂŒsselt und beim Speichern wieder verschlĂŒsselt): ```bash sops apps/production/custom-configs/mas-secrets.sops.yaml ``` ----- ## 6\. Troubleshooting & Known Issues ### Issue 1: `HelmChart is not ready: stat ... no such file or directory` * **Ursache:** Falscher Versuch, das Chart direkt aus dem GitHub-Repo-Code (als GitRepository) zu lesen. Das Chart erfordert Sub-Charts, die so nicht gerendert werden können. * **Lösung:** Immer das OCI-Repository (`oci://ghcr.io/...`) und den Chartnamen `matrix-stack` verwenden. ### Issue 2: `values don't meet the specifications of the schema(s)` * **Ursache:** Ab Version 26.x hat ESS ein sehr rigides JSON-Schema. * **Lösung:** Logs genau lesen. * `tls` darf nicht in den Ingress-Block der Komponenten. * `serverName` muss ins Top-Level, nicht unter `synapse`. * Keine `config:` Blöcke fĂŒr Core-Komponenten. ### Issue 3: Let's Encrypt Error `403 Order's status is processing` auf der Hauptdomain * **Ursache (Die ACME Race Condition):** Wenn `elementWeb` (auf `axion1337.chat`) und `wellKnownDelegation` (ebenfalls auf `axion1337.chat`) gleichzeitig aktiviert sind, fordert `cert-manager` zeitgleich zwei Zertifikate fĂŒr dieselbe Domain an. Let's Encrypt blockt den zweiten Versuch und das Ingress-Setup hĂ€ngt sich auf. * **Lösung:** `wellKnownDelegation: enabled: false` im Helm-Chart setzen. Das `.well-known/matrix/server` File muss stattdessen entweder als statische JSON-Datei auf dem Webserver der Hauptdomain hinterlegt oder per Ingress-Route (Traefik Middleware) direkt auf den Synapse-Dienst umgebogen werden. ### Issue 4: Fehlende Zertifikate (`No resources found`) * **Ursache:** Manuelle Kustomize-Patches kollidieren mit dem Helm-Chart. * **Lösung:** Manuelle Patches löschen und das native Feature des Charts nutzen: `certManager: true` auf der obersten (Root-)Ebene der `values` setzen. Das Chart erstellt daraufhin die korrekten Ingress-Annotations und Secrets von selbst.