software steht so weit.

jetzt build + docker build und testen
This commit is contained in:
br committed 2026-10-02 13:25:34 +02:00
1 parent 42f0c0accb
commit ca6cdcca63
90 files changed
+10298 -480

No files matched your search

+114 -10
View File
@@ -36,28 +36,79 @@ Die ausführliche Architektur steht in [.ai/sultan-system-architecture.md](.ai/s
### Voraussetzungen
- Go (aktuelle stabile Version)
- Zum Bauen: Go (Version laut `go.mod`) bzw. Docker mit buildx
- Für den Ingress-Knoten: Traefik v3
- Für Docker-Hosts: Zugriff auf `/var/run/docker.sock`
### Binary bauen
### 1. Quellen holen
```bash
git clone ssh://git@git.everdc.eu:10022/chmln-app-dev/sultan.git
cd sultan
go build -o sultan .
./sultan version
sudo install -m 0755 sultan /usr/local/bin/sultan
```
### 2. Binary bauen (amd64 + arm64)
```bash
go build -o sultan . && ./sultan version # schnell, nur für die eigene Architektur
deploy/build.sh # Release-Binaries für linux/amd64 + linux/arm64
# → dist/<version>/sultan_linux_amd64, sultan_linux_arm64, SHA256SUMS
sudo install -m 0755 dist/<version>/sultan_linux_amd64 /usr/local/bin/sultan
```
Die Version kommt aus `git describe` (Tag, sonst Commit-Hash; `-dirty` bei uncommitteten Änderungen) und steht in `sultan version`.
### 3. Docker-Image bauen (ein Image für Server *und* Agent, amd64 + arm64)
```bash
docker build -t sultan:latest . # lokal, eigene Architektur
docker run --rm sultan:latest sultan version
```
Das Image ist distroless (nur das statische Binary, ~17 MB) und läuft als nonroot-User `65532`. Die Rolle wählt der Befehl: `sultan server …` bzw. `sultan agent …`.
### 4. Image in die Gitea-Registry schieben
```bash
docker login git.everdc.eu # einmalig: Gitea-User + Token mit Scope write:package
deploy/push-image.sh # → git.everdc.eu/chmln-app-dev/sultan:<version>
LATEST=1 deploy/push-image.sh # zusätzlich :latest (nur für Releases)
```
Baut per `docker buildx` gleichzeitig für `linux/amd64` und `linux/arm64` (Go kompiliert quer, kein QEMU nötig) und verweigert Versionen mit `-dirty`. Anpassbar über `REGISTRY`, `OWNER`, `PLATFORMS`.
### 5. Binaries auf den statischen Webhost legen
```bash
TARGET=deploy@webdocker11:/srv/inst/htdocs deploy/publish-static.sh
STABLE=1 TARGET=… deploy/publish-static.sh # zusätzlich sultan/releases/stable setzen
```
Ablage per `rsync` unter `sultan/releases/<version>/` (Binaries + `SHA256SUMS`); ältere Versionen bleiben herunterladbar. Grundlage für das spätere `curl … | bash`.
### 6. Mit Docker Compose betreiben
Vorlagen: [deploy/compose/server](deploy/compose/server) (Ingress-Knoten neben Traefik) und [deploy/compose/agent](deploy/compose/agent) (Docker-Host).
```bash
cp -r deploy/compose/server ~/sultan-server && cd ~/sultan-server
cp .env.example .env && $EDITOR .env # SULTAN_IMAGE, SULTAN_PUBLIC_URL
sudo install -d -m 0700 -o 65532 -g 65532 suldata # Datenverzeichnis für den nonroot-User
docker compose up -d
docker compose exec sultan-server sultan token tenant add --id=… --domains=…
docker compose exec sultan-server sultan token invite --tenant=…
```
Der Agent läuft mit `network_mode: host`. Nur so meldet er die Host-IP als Backend-Adresse (statt der Container-IP) und den Hostnamen als Knoten-ID. Für den Docker-Socket braucht er `DOCKER_GID` in der `.env` (`getent group docker | cut -d: -f3`).
### Server starten (Ingress-Knoten)
```bash
sultan server # Daten landen in ./suldata
sultan server --public-url=https://ingress.example.com:8443 # Daten landen in ./suldata
sultan server --help # alle Optionen
```
Der Server lauscht auf `:8443` für Agents und auf `127.0.0.1:8080` für Traefik (beides per `--agent-addr` / `--provider-addr` änderbar). Im Verzeichnis `./suldata` liegen Datenbank und Schlüssel – bitte sichern 🔑 und nie einchecken. Traefik bindest du über den HTTP-Provider an:
Alle Optionen gehen auch als Umgebungsvariable, z. B. `SULTAN_PUBLIC_URL=… sultan server` (praktisch für Docker und systemd). Der Server lauscht auf `:8443` für Agents und auf `127.0.0.1:8080` für Traefik (beides per `--agent-addr` / `--provider-addr` änderbar). Im Verzeichnis `./suldata` liegen Datenbank und Schlüssel – bitte sichern 🔑 und nie einchecken. Traefik bindest du über den HTTP-Provider an:
```bash
--providers.http.endpoint=http://127.0.0.1:8080/v1/traefik-config
@@ -66,13 +117,66 @@ Der Server lauscht auf `:8443` für Agents und auf `127.0.0.1:8080` für Traefik
### Agent verbinden (Backend-Host)
1. Auf dem Server mit `sultan token` einen Einladungs-Token erzeugen 🎟️
1. Auf dem Server einen Mandanten anlegen und eine Einladung erzeugen 🎟️
```bash
sultan token tenant add --id=homelab --name="Mein Homelab" --email=ich@example.com --domains="example.com,*.example.com"
sultan token invite --tenant=homelab # gibt die Einladung aus, 24 h gültig
sultan token --help # alle Verwaltungsbefehle
```
2. Auf dem Backend-Host den Agent starten:
```bash
sultan agent --server=https://ingress.example.com:8443 --token=<einladungs-token>
SULTAN_TOKEN=<einladung> sultan agent # Adresse steckt in der Einladung (sultan server --public-url=…)
sultan agent --server=https://ingress.example.com:8443 --token=<einladung> # sonst Adresse angeben
# danach genügt:
sultan agent
```
Der Agent liest die Container mit `traefik.enable=true` aus Docker und meldet sie an den Server. Wichtig: Der Ingress erreicht nur **veröffentlichte** Ports (`ports: "8081:80"`), nicht solche, die nur auf `127.0.0.1` veröffentlicht sind. Ohne Docker: `--docker-socket=none`. Über welche Adresse der Ingress den Host erreicht, ermittelt der Agent automatisch; für NetBird z. B. `--backend-interface=wt0`.
**Ohne Docker (Bare-Metal, LAMP …)** 🖥️ beschreibst du deine Dienste in `/etc/sultan.d/*.yaml`:
```yaml
services:
- name: kunde-a
url: http://127.0.0.1:8080
hosts: [kunde-a.de]
https: true
redirect_http_to_https: true
redirect_www: to_non_www
healthcheck: { expect_title: "KundeA - Willkommen" } # bei Ausfall: Wartungsseite statt Fehler
```
Beim ersten Verbinden merkt sich der Agent den Fingerprint des Servers – ab dann läuft alles automatisch. 🎉
Fertige Docker-Compose-Beispiele für Ingress und Backend-Host findest du in der [Architektur-Doku](.ai/sultan-system-architecture.md#7-referenzkonfigurationen).
### Wartung 🔧
```bash
sultan agent maintenance on --for 2h --public-reason "Wir spielen ein Sicherheitsupdate ein." # auf dem Knoten
sultan token node maintenance --id=pi --for 2h # oder auf dem Server
sultan token node resume --id=pi # beenden
```
Besucher sehen währenddessen die Wartungsseite mit Grund und voraussichtlichem Ende – auch, wenn der Knoten gerade neu startet.
### Monitoring & Benachrichtigungen 📊
```bash
sultan server --notify-slack=https://hooks.slack.com/… --notify-ntfy=https://ntfy.sh/mein-sultan
curl -s http://127.0.0.1:8080/metrics/checkmk # Checkmk Local Checks: Verträge, Zahlungen, Knoten
```
Sultan meldet ablaufende Verträge, Mahnstufen, ausgefallene Knoten und Policy-Verstöße – jedes Ereignis genau einmal.
### Hinweis- und Wartungsseiten 🚧
Fällt ein Dienst aus oder läuft ein Abo ab, zeigt Sultan statt eines Fehlers eine freundliche Seite (Deutsch und Englisch). Eigene Gestaltung:
```bash
sultan dump-landing # Vorlagen nach ./suldata/landing – anpassen, wirkt sofort
sultan server --hoster-name="Mein Hosting" --hoster-url=https://hosting.example
```
Fertige Docker-Compose-Vorlagen für Ingress und Backend-Host liegen unter [deploy/compose](deploy/compose).