Almost every tracked file in the repo had drifted to mode 777 on disk (only files created fresh this session were unaffected), and a chunk of that drift had already been committed as spurious +x bits on plain YAML/Markdown files (authentik.yaml, kustomization.yaml, coturn.yaml, element-server-suite.yaml, TASKS.md, install.md, etc.) - none of these need to be executable. Restored to 644 for regular files, 755 only for actual scripts (postCreateCommand.sh, docker-init.sh, install-hooks.sh, pre-commit hook, element-setup-linux.sh). Also found element-setup-macos.command was missing +x despite having a shebang and being meant for double-click execution on macOS - fixed. Added .gitignore for .DS_Store and .claude/ and stopped tracking the five .DS_Store files that had been committed by accident. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
106 lines
4.4 KiB
Markdown
106 lines
4.4 KiB
Markdown
## 🚀 Step-by-Step Installationsanleitung (From Scratch)
|
|
|
|
Diese Anleitung geht davon aus, dass du einen frischen Server (Ubuntu/Debian) mit öffentlicher IP hast und deine lokalen Tools (Flux CLI, kubectl, sops, age) installiert sind.
|
|
|
|
### Schritt 1: Kubernetes (K3s) auf dem Server installieren
|
|
Logge dich per SSH auf deinem Server ein und installiere ein frisches K3s. Wir nutzen K3s mit dem Standard-Traefik-Ingress.
|
|
|
|
```bash
|
|
# Auf dem Server ausführen:
|
|
curl -sfL https://get.k3s.io | sh -
|
|
|
|
# Kubeconfig kopieren und Berechtigungen setzen (für den lokalen Zugriff)
|
|
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
|
|
sudo chown $USER ~/.kube/config
|
|
```
|
|
*Kopiere dir den Inhalt der `~/.kube/config` auf deinen lokalen Rechner, damit dein lokales `kubectl` den Server steuern kann. Vergiss nicht, die IP `127.0.0.1` in der Datei durch die öffentliche IP deines Servers zu ersetzen.*
|
|
|
|
### Schritt 2: Den SOPS-Verschlüsselungs-Key generieren
|
|
Damit Flux deine verschlüsselten Passwörter (SMTP, Datenbank) im Cluster lesen kann, braucht es einen privaten Schlüssel. Wir nutzen `age`.
|
|
|
|
```bash
|
|
# Auf deinem lokalen Rechner ausführen:
|
|
# 1. Key generieren
|
|
age-keygen -o age.agekey
|
|
|
|
# 2. Den Public Key (steht in der Datei) in die .sops.yaml des Repos eintragen!
|
|
|
|
# 3. Den Private Key als Secret in den Cluster laden (in den flux-system Namespace)
|
|
cat age.agekey | kubectl create secret generic sops-age \
|
|
--namespace=flux-system \
|
|
--from-file=age.agekey=/dev/stdin
|
|
```
|
|
|
|
### Schritt 3: Das Git-Repository vorbereiten
|
|
Stelle sicher, dass deine GitOps-Struktur gepusht ist und du ein Personal Access Token (PAT) für dein Git-Repository hast (bei GitHub/GitLab).
|
|
* Das Token benötigt Lese- und Schreibrechte auf das Repository.
|
|
|
|
### Schritt 4: Flux Bootstrap (Der Startschuss)
|
|
Das ist der magische Befehl. Er installiert den Flux-Controller in deinem Cluster und verbindet ihn mit deinem Repository. Ab diesem Moment übernimmt Flux das Steuer.
|
|
|
|
**Für GitHub:**
|
|
```bash
|
|
export GITHUB_TOKEN="dein-personal-access-token"
|
|
export GITHUB_USER="dein-github-username"
|
|
|
|
flux bootstrap github \
|
|
--owner=$GITHUB_USER \
|
|
--repository=dein-repo-name \
|
|
--branch=main \
|
|
--path=prod/gitops/clusters/matrix \
|
|
--personal
|
|
```
|
|
|
|
**Für Gitea/GitLab/Generisches Git (wie in deinem Setup scheinbar genutzt):**
|
|
```bash
|
|
flux bootstrap git \
|
|
--url=https://rohana.axion1337.de/sorb/axion1337.chat-gitops.git \
|
|
--branch=main \
|
|
--path=prod/gitops/clusters/matrix \
|
|
--username=dein-git-user \
|
|
--password=dein-git-token
|
|
```
|
|
|
|
### Schritt 5: Zurücklehnen und beobachten
|
|
Flux klont jetzt dein Repo, liest die Kustomizations und wendet sie in der richtigen Reihenfolge an (`infra-apps` -> `production-apps`).
|
|
|
|
Du kannst den Fortschritt live verfolgen:
|
|
```bash
|
|
# Zeigt den GitOps-Sync-Status:
|
|
flux get kustomizations --watch
|
|
|
|
# Zeigt das Helm-Deployment der Element Server Suite:
|
|
flux get helmreleases -n matrix --watch
|
|
|
|
# Zeigt, wie die Pods hochfahren:
|
|
kubectl get pods -n matrix -w
|
|
```
|
|
Sobald alle Pods auf `Running` stehen und die Zertifikate über Let's Encrypt validiert wurden (`kubectl get certificate -n matrix`), ist dein Matrix-Stack unter `https://axion1337.chat` erreichbar.
|
|
|
|
---
|
|
|
|
## 🔁 Recovery: lokalen age-Key wiederherstellen (Server läuft bereits)
|
|
|
|
Anders als Schritt 2 oben (neuen Key **erzeugen**) — falls der Server bereits läuft und nur der
|
|
lokale Rechner den age-Key verloren hat (z.B. nach einer Neuinstallation), lässt sich der
|
|
**bestehende** Private Key direkt aus dem Cluster zurückholen, ohne einen neuen zu generieren
|
|
(das würde `.sops.yaml` und alle bereits verschlüsselten Secrets ungültig machen):
|
|
|
|
```bash
|
|
mkdir -p ~/.age
|
|
kubectl get secret sops-age -n flux-system -o jsonpath='{.data.age\.agekey}' | base64 -d > ~/.age/keys.txt
|
|
chmod 600 ~/.age/keys.txt
|
|
|
|
# Public Key zur Kontrolle gegen .sops.yaml abgleichen:
|
|
grep 'public key:' ~/.age/keys.txt
|
|
grep 'age:' .sops.yaml
|
|
```
|
|
|
|
Voraussetzung: laufender Kubeconfig-Zugriff auf den Cluster (siehe Schritt 1 oben — auch das
|
|
ist reines Zurückkopieren, kein Neu-Erzeugen).
|
|
|
|
**Bekannte Schwachstelle**: Dieser Key existiert aktuell nur an zwei Orten — im
|
|
`sops-age`-Secret selbst (auf demselben Server) und lokal bei wem auch immer ihn zuletzt
|
|
zurückgeholt hat. Es gibt kein separates, offsite Backup. Fällt der Server komplett aus
|
|
(nicht nur der lokale Rechner), sind alle SOPS-verschlüsselten Secrets im Repo unlesbar.
|
|
Siehe Issue-Backlog für die Entscheidung, ob/wie das abgesichert wird. |