- Add pre-commit hook (scripts/hooks/pre-commit) that automatically calculates MD5 checksums of ConfigMaps (element-values.yaml, synapse-values.yaml) - Update annotations in kustomization.yaml to trigger Flux CD HelmRelease syncs - Add install script (scripts/install-hooks.sh) for easy hook setup - Add comprehensive documentation (docs/ops-configmap-sync.md) explaining: * Why Flux doesn't auto-detect ConfigMap changes * How the checksum-based workaround works * How to install and use the hook * Troubleshooting and manual sync procedures - Update README.md with post-clone hook installation step This solves the issue where Flux CD doesn't automatically re-deploy when external ConfigMaps are modified. Users no longer need manual checksum updates. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
247 lines
9.9 KiB
Markdown
247 lines
9.9 KiB
Markdown
# 🚀 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\!**
|
||
|
||
<!-- end list -->
|
||
|
||
```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 <name> -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. |