todo-tree stopped triggering on docs/TASKS.md because the file was restructured (2026-07-28 backlog migration) to use plain markdown checkboxes with no literal TODO/FIXME/etc. keywords, which is all todo-tree's default config matches on. Added the documented todo-tree.regex.regex + [ ]/[x] tags configuration (see Gruntfuggly/todo-tree wiki) so it actually detects checkbox items, plus red/green highlighting for open vs done. Also cleaned up 19 stale open checkbox items left behind by that same migration - they duplicated content already tracked as individual Gitea issues (in old pre-migration detail, not the established "-> Issue #N" pointer format the rest of the file already uses), including two (Database Backup Strategy, Synapse Media PVC Backups) for issues that are actually already closed. Converted all to pointer format or removed where closed. Replaced the stale M1-M7 milestone table (contradicted its own file header - said M4 "In Progress" while the summary line above already said 0 in progress) with a pointer to the new SemVer Releases. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
🐳 DevContainer für ESS Community GitOps
Dieses DevContainer-Setup ermöglicht dir, auf macOS, Windows und Linux einheitlich zu entwickeln.
🚀 Schnelstart
VSCode mit Remote Containers Extension
-
VSCode Extension installieren:
- Öffne VSCode → Extensions → Suche nach
Dev Containers(Microsoft) - Installiere sie
- Öffne VSCode → Extensions → Suche nach
-
GitOps Verzeichnis öffnen:
cd "april mit Ansible/prod/gitops" code . -
DevContainer starten:
- Klick auf
><Symbol unten links in VSCode - Wähle
Reopen in Container - Warte, bis das Image gebaut wurde (~3-5 Min beim ersten Mal)
- Klick auf
Alternative: Docker + CLI
docker build -t ess-gitops .devcontainer
docker run -it --rm \
-v ~/.kube:/home/vscode/.kube \
-v ~/.ssh:/home/vscode/.ssh \
-v ~/.age:/home/vscode/.age \
-v /var/run/docker.sock:/var/run/docker.sock \
ess-gitops
📦 Enthaltene Tools
- kubectl - Kubernetes CLI
- flux - FluxCD GitOps Controller CLI
- helm - Kubernetes Package Manager
- sops - Secret Operations (Verschlüsselung)
- age - Modern File Encryption
- docker - Container CLI (über Host-Socket)
- git - Versionskontrolle
- jq/yq - JSON/YAML Processing
- zsh + oh-my-zsh - Shell mit Plugins
🔐 Wichtige Verzeichnis-Binds
Der Container mountet automatisch:
| Host | Container | Zweck |
|---|---|---|
~/.kube |
/home/vscode/.kube |
Kubernetes Config |
~/.ssh |
/home/vscode/.ssh |
SSH Keys |
~/.age |
/home/vscode/.age |
Age Encryption Keys |
/var/run/docker.sock |
/var/run/docker.sock |
Docker Daemon (für docker Befehle) |
⚙️ Kubeconfig Einrichten
-
Host-Machine (z.B. macOS):
# Stelle sicher, dass ~/.kube/config existiert und den richtigen Cluster enthält kubectl get nodes -
Im Container:
kubectl get nodes # Sollte jetzt auch dein Cluster zeigen kubectl config current-context
🔐 SOPS + Age Setup
Damit du Secrets bearbeiten kannst, brauchst du den privaten age-Key. Dieser ist in .sops.yaml konfiguriert.
Schritt 1: Age-Key bereitstellen
# Host-Machine: Key-Datei erstellen
mkdir -p ~/.age
# Füge deinen privaten Key ein (Format: "age-secret-key-...")
echo "age-secret-key-xxx..." > ~/.age/keys.txt
chmod 600 ~/.age/keys.txt
Schritt 2: Im Container konfigurieren
Der Container mounted ~/.age automatisch. Setze die Umgebungsvariable:
# Im Container-Terminal (SOPS_AGE_KEY_FILE ist bereits automatisch gesetzt!)
# Jetzt kannst du Secrets bearbeiten (wird transparent ver-/entschlüsselt):
sops apps/production/custom-configs/mas-secret.yaml
Schritt 3: VSCode Integration (optional)
Um die Umgebungsvariable beim Start zu setzen, nutze die .devcontainer/devcontainer.json:
"remoteEnv": {
"KUBECONFIG": "/home/vscode/.kube/config",
"SOPS_AGE_KEY_FILE": "/home/vscode/.age/keys.txt"
}
Wie es funktioniert
.sops.yamldefiniert, dass Secrets mitageverschlüsselt werden- Beim Öffnen mit
sops <datei>wird die Datei entschlüsselt → du editierst den plaintext in deinem Editor - Beim Speichern wird alles wieder automatisch verschlüsselt
- Wichtig: Niemals den plaintext-Buffer commiten!
📝 Nach Container-Start: Git Hooks Installieren
Wichtig für die ConfigMap Auto-Sync (verhindert Merge-Konflikte):
./scripts/install-hooks.sh
Mehr Details: docs/ops-configmap-sync.md
📝 Nützliche Befehle
# Status des Deployments
kubectl get pods -n matrix
flux get helmreleases -A
# Secrets bearbeiten (mit verschlüsselung)
sops apps/production/custom-configs/mas-secret.yaml
# FluxCD Sync erzwingen
flux reconcile kustomization production-apps --with-source
# Zertifikate debuggen
kubectl get certificate -n matrix
kubectl describe certificate matrix-ingress -n matrix
# HelmRelease Status prüfen
flux describe helmrelease matrix-stack -n matrix
🛠️ Anpassungen für Windows/WSL2
Falls du Windows nutzt:
- Docker Desktop installieren (mit WSL2 Backend)
- VSCode mit WSL Extension öffnen
- Im WSL Terminal:
cd /mnt/c/path/to/projekt code . - Dann
Dev Containers: Reopen in Container
Das funktioniert seamless, weil Docker Desktop unter WSL2 läuft.
🔧 Troubleshooting
Problem: SOPS_AGE_KEY_FILE not found
Lösung: Key muss in ~/.age/keys.txt auf der Host-Machine sein:
# Host
mkdir -p ~/.age
echo "your-age-private-key" > ~/.age/keys.txt
Der Container mountet ~/.age automatisch → sollte dann funktionieren.
Problem: kubectl: connection refused
Lösung: ~/.kube/config muss auf Host vorhanden sein:
# Host
kubectl get nodes # Test, ob Zugriff existiert
# Dann Container neustarten
Problem: HelmChart is not ready: stat ... no such file or directory
Siehe README.md → Issue 1. Kontrolliere:
HelmRepositorynutzttype: oci- URL ist
oci://ghcr.io/element-hq/ess-helm
Problem: values don't meet the specifications of the schema
Siehe README.md → Issue 2. Häufige Fehler:
tls:darf nicht imingress:Block seinserverNamemuss auf Root-Ebene dervaluesstehen- Komponenten-Namen:
camelCase(z.B.elementWeb,matrixAuthenticationService)
Problem: Let's Encrypt 403 Order's status is processing
Siehe README.md → Issue 3. Kurz:
wellKnownDelegation: enabled: falsesetzen- Oder
.well-known/matrix/servermanuell aufelementWebweiterleiten
⚠️ Wartungshinweis: Warum dieser Container regelmäßig getestet werden muss
Der Dockerfile installiert mehrere Tools über externe apt-Repos und Install-Skripte
(pkgs.k8s.io, download.docker.com, GitHub-Releases, fluxcd.io/ohmyzsh.sh
Installer). Diese Quellen sind nicht unter unserer Kontrolle und können jederzeit
brechen — genau das ist am 2026-07-28 passiert: der Container konnte seit
Fertigstellung nie erfolgreich gebaut werden, ohne dass es jemand bemerkt hat, weil
niemand ihn zwischenzeitlich tatsächlich gebaut hat. Gefundene und behobene Probleme:
| # | Problem | Ursache | Fix |
|---|---|---|---|
| 1 | apt.kubernetes.io → 404 Not Found |
Google hat das alte Kubernetes-apt-Repo 2023 abgeschaltet | Umgestellt auf das offizielle Nachfolge-Repo pkgs.k8s.io (versioniert pro k8s-Minor-Version, aktuell v1.34) |
| 2 | docker-ce-cli "has no installation candidate" auf Apple Silicon |
Repo-Zeile hatte arch=amd64 hartkodiert, Build lief aber auf arm64 |
arch=$(dpkg --print-architecture) zur Build-Zeit ermitteln |
| 3 | useradd: group 'docker' does not exist |
Nur die Docker-CLI wird installiert (kein Daemon), daher legt kein Paket die docker-Gruppe automatisch an |
groupadd docker explizit vor useradd |
| 4 | oh-my-zsh-Install schlägt mit Quoting-Fehler fehl | Verschachtelte sh -c '...'-Anführungszeichen in einer Zeile |
Install-Skript erst in eine Datei laden, dann sauber mit su - vscode -c "sh /tmp/install-omz.sh --unattended" ausführen |
| 5 | sops-Binary war hart auf linux.amd64 gepinnt |
Lief auf Apple Silicon nur zufällig per QEMU-Emulation von Docker Desktop mit, nicht nativ | Arch dynamisch über dpkg --print-architecture auflösen (linux.arm64 / linux.amd64) |
| 6 | docker.sock-Zugriff im Container: permission denied |
Der gemountete Host-Socket gehört (je nach Docker-Setup) einer Gruppe/GID, die im Container nicht existiert oder nicht der docker-Gruppe entspricht (auf Docker Desktop für Mac/Windows z.B. GID 0/root statt einer eigenen docker-Gruppe) |
docker-init.sh: Root-Entrypoint gleicht beim Container-Start die GID der docker-Gruppe an den tatsächlich gemounteten Socket an (bzw. tritt der GID-Inhaber-Gruppe bei, falls die GID schon vergeben ist), wechselt danach per gosu zu vscode |
Konsequenz für die Zukunft: Vor jeder größeren Änderung an .devcontainer/ (oder
mindestens vierteljährlich) einmal real bauen und laufen lassen:
docker build -f .devcontainer/Dockerfile -t ess-gitops-devcontainer-test .devcontainer
docker run --rm \
-v ~/.kube:/home/vscode/.kube \
-v ~/.age:/home/vscode/.age \
-v /var/run/docker.sock:/var/run/docker.sock \
ess-gitops-devcontainer-test bash -c '
kubectl version --client && helm version --short && flux --version && \
sops --version && age --version && docker version --format "{{.Server.Version}}" && \
id vscode
'
Wenn docker version hier den echten Server, nicht nur die Client-Version zeigt, und
id vscode die passende Docker-Gruppe/GID auflistet, funktioniert der Socket-Zugriff
tatsächlich — nicht nur der Build.
📚 Weitere Ressourcen
- Dev Containers Docs
- FluxCD Dokumentation
- SOPS Anleitung
- Projekt-README:
README.md(Architektur, Issues, Best Practices) - Setup-Docs:
docs/setup/ - Install-Guide:
docs/install.md