Initial version of the Hermes self learning agent setup of JR IT Services.

This commit is contained in:
2026-04-21 11:53:29 +02:00
commit 7f9b0e6c5f
31 changed files with 1966 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
# Architektur
## Ziele
- Hermes parallel zu OpenClaw betreiben, ohne Port-, Volume- oder Netzwerk-Kollisionen.
- Reproduzierbares Setup fuer eine Arch-Linux-Workstation.
- Resilienter Betrieb mit Healthchecks, Restart-Policy, Backups und Update-Weg.
- Komfortabler Workflow ueber ein einziges Wrapper-Skript.
- Internetzugang fuer Hermes ueber die Host-Bridge `br0`.
## Trennungsprinzipien
### 1. Eigene Datenverzeichnisse
- Hermes: `./state/hermes`
- OpenClaw: separat, z. B. `./state/openclaw`
Hermes schreibt seine komplette Identitaet, Konfiguration, Skills, Sessions und Memory in das gemountete Datenverzeichnis. Das darf nicht mit einem zweiten Hermes-Gateway geteilt werden.
### 2. Eigene Host-Ports
Default in diesem Repo:
- Hermes API: `127.0.0.1:18642 -> 8642`
- Hermes Dashboard: `127.0.0.1:19119 -> 9119`
Die absichtlich ungewohnten Host-Ports reduzieren Kollisionen mit anderen lokalen Stacks. Dass die Bindung auf `127.0.0.1` erfolgt, ist Absicht: der LAN-Uplink laeuft separat ueber `br0`, die Bedienoberflaechen bleiben lokal.
### 3. Eigene Netzrollen
- `hermes_private`: internes Docker-Bridge-Netz fuer Compose-interne Kommunikation
- `br0_uplink`: externes Docker-Macvlan-Netz auf Parent `br0`
- `alan_agents_shared`: optionales Querverbindungsnetz fuer Hermes/OpenClaw
Damit ist die Verkehrsrichtung klar getrennt:
- Internet/LAN raus ueber `br0_uplink`
- interne Service-Aufloesung ueber `hermes_private`
- bewusste Interconnects ueber `alan_agents_shared`
### 4. Eigene Compose-Projektkennung
Der Standard-Projektname ist `alan`. Dadurch bleiben Container, Netzwerke und sonstige Docker-Ressourcen sauber benannt.
## Resilienz
- `restart: unless-stopped`
- HTTP-Healthchecks fuer Gateway und Dashboard
- `no-new-privileges`
- definierte Ressourcenlimits
- Backup- und Restore-Skripte
- idempotentes Bootstrap fuer `.env`, Verzeichnisse und Shared-Netz
- explizite Validierung des externen `br0`-Netzes vor dem Start
## Nicht absichtlich eingebaut
- kein Reverse-Proxy per Default
- kein gemeinsamer Docker-Socket fuer Hermes und OpenClaw
- kein wildes Mounten von `/home`
- kein direkter Zwang, OpenClaw in denselben Compose-Stack zu ziehen
- keine blind automatische Ermittlung deiner LAN-Parameter
Das ist Absicht: weniger Seiteneffekte, weniger Sicherheitsrisiko, bessere Fehlersuche.
+66
View File
@@ -0,0 +1,66 @@
# Betrieb ueber `br0`
## Warum hier Macvlan verwendet wird
Du hast vorgegeben, dass der Container **ueber deine Bridge `br0`** laufen soll, wenn Internetzugang benoetigt wird.
Fuer Docker auf Linux ist das sauberste Muster dafuer in der Regel ein **externes Macvlan-Netz** mit:
- Parent: `br0`
- eigenem IP-Bereich fuer Container
- optionaler statischer IP pro Service
## Was du in `.env` anpassen musst
Mindestens:
```dotenv
BR0_PARENT=br0
BR0_SUBNET=192.168.10.0/24
BR0_GATEWAY=192.168.10.1
BR0_IP_RANGE=192.168.10.224/28
BR0_DOCKER_NETWORK=br0_lan
```
Optional:
```dotenv
BR0_HOST_SHIM_CIDR=192.168.10.239/32
```
Nimm fuer `BR0_IP_RANGE` am besten einen kleinen Bereich, der **nicht** durch DHCP an normale Clients vergeben wird.
## Externes Docker-Netz anlegen
```bash
./scripts/alanctl net-create-br0
```
Das erzeugt ein Docker-Macvlan-Netz auf `br0`.
## Bekannte Einschraenkung: Host <-> Container
Bei Macvlan koennen Host und Container standardmaessig **nicht direkt miteinander sprechen**. Das ist kein Fehler in deinem Compose-Setup, sondern normales Macvlan-Verhalten.
### Loesung: Host-Shim anlegen
```bash
./scripts/alanctl net-create-shim
```
Das erzeugt auf dem Host ein zusaetzliches Macvlan-Interface und routet den konfigurierten IP-Bereich dorthin.
## Wann du den Shim wirklich brauchst
- du willst den Container auf seiner `br0`-IP direkt vom Host anpingen
- du willst vom Host Dienste auf der `br0`-IP ansprechen
Wenn dir dagegen die lokal publizierten Ports `127.0.0.1:18642` und `127.0.0.1:19119` reichen, brauchst du den Shim oft gar nicht.
## Empfehlung fuer parallelen OpenClaw-Betrieb
- gleicher Parent `br0`
- anderer Host-Port
- anderer Volume-Pfad
- eigene statische IP oder eigene Zuteilung aus demselben `BR0_IP_RANGE`
- kein gemeinsames wildes Mounten von Host-Pfaden
+84
View File
@@ -0,0 +1,84 @@
# Gitea-Import
## Repo-Name
Empfohlen: `alan-agents-workstation`
## Schnellweg
```bash
cd /pfad/zu/alan
git init
git branch -M main
git add .
git commit -m "Initial workstation stack for Hermes + OpenClaw coexistence"
git remote add origin ssh://git@<dein-gitea-host>/<dein-user>/alan-agents-workstation.git
git push -u origin main
```
## Branching
Einfach und robust fuer Single-Workstation-Infra:
- `main` fuer den stabilen Stand
- `feat/...` fuer lokale Erweiterungen
- Tags fuer getestete Snapshots, z. B. `v0.1.0`
## Was ins Repo gehoert
- Compose-Dateien
- Skripte
- Doku
- Beispiel-Env-Dateien
- systemd-User-Units
## Was nicht ins Repo gehoert
- echte API-Keys
- echte Hermes-Daten aus `state/hermes`
- Backup-Archive
- lokale Debug-Logs
## Empfohlene Zusatzdateien fuer Gitea
Dieses Repo bringt bereits mit:
- `CHANGELOG.md`
- `CONTRIBUTING.md`
- `.gitea/ISSUE_TEMPLATE/*`
- `.gitea/pull_request_template.md`
- `.gitea/workflows/repo-check.yml`
- `docs/release-process.md`
- `docs/upgrade-policy.md`
Damit bekommst du in Gitea:
- strukturierte Fehlermeldungen und Feature-Wuensche
- einheitliche PR-Checklisten
- einfache serverseitige Grundpruefungen fuer das Repo
- nachvollziehbare Releases mit Tagging und Upgrade-Hinweisen
## Release-Empfehlung
Fuer jedes verteilte Repo-Update:
1. `CHANGELOG.md` pflegen
2. `./scripts/release-check` ausfuehren
3. Release-Tag setzen, z. B. `v0.1.1`
4. in Gitea Release Notes mit Upgrade-Hinweisen anlegen
## Beispiel fuer Release Notes
```text
Neu:
- robusteres br0-Uplink-Handling
- verbesserter Rollback-Workflow
Wichtig fuer bestehende Installationen:
- `.env.example` geaendert: neuer Key XYZ
- vor Upgrade bitte `./scripts/alanctl backup` ausfuehren
- Rollback bleibt ueber `./scripts/alanctl rollback-hermes` moeglich
```
+57
View File
@@ -0,0 +1,57 @@
# Hermes in diesem Setup
## Betriebsmodus
Dieses Repo faehrt Hermes **im Container** als Gateway.
Wichtige Daten landen in `./state/hermes`, das auf `/opt/data` im Container gemountet wird. Laut offizieller Doku ist `/opt/data` der Single Source of Truth fuer Config, Sessions, Skills, Memories und Logs.
## Initialisierung
1. `./scripts/alanctl bootstrap`
2. `./scripts/alanctl init-hermes`
3. `./scripts/alanctl up`
`init-hermes` startet den offiziellen Setup-Wizard interaktiv.
## Dashboard
Optional:
```bash
./scripts/alanctl up --dashboard
```
Danach ist das Dashboard standardmaessig auf `http://127.0.0.1:19119` erreichbar.
## Wichtige Hinweise
- Nicht zwei Hermes-Gateway-Container gegen dasselbe Datenverzeichnis starten.
- Falls du spaeter Messaging-Plattformen oder Provider-Keys nutzt, verwalte sie im Hermes-Datenordner bzw. in dessen `.env`.
- Fuer Browser-Tools ist `shm_size=1g` gesetzt.
## Update-Betrieb
Empfohlener Alltag:
```bash
./scripts/alanctl pin-hermes stable
./scripts/alanctl update-hermes
```
Gezieltes Upgrade auf einen bestimmten Tag:
```bash
./scripts/alanctl update-hermes v0.9.3
```
Der Update-Workflow macht automatisch:
1. Backup des Hermes-State
2. Pull des Ziel-Images
3. Recreate des Containers
4. Warten auf erfolgreichen Healthcheck
5. automatisches Zurueckstellen auf den vorherigen Tag bei Fehlern
Der zuletzt erfolgreiche Stand wird lokal gespeichert und kann mit `rollback-hermes` erneut ausgerollt werden.
+47
View File
@@ -0,0 +1,47 @@
# Maintainers and Review Ownership
Dieses Repo ist so klein gehalten, dass eine schlanke Maintainer-Struktur sinnvoller ist als komplexe Freigaberegeln.
## Primaerer Maintainer
- `@johannes`
## Verantwortungsbereiche
- **Runtime / Compose / Netzlogik**
- `compose.yaml`
- `compose/`
- `scripts/`
- `systemd/`
- **Dokumentation / Betriebswissen**
- `docs/`
- `README.md`
- `CHANGELOG.md`
- `CONTRIBUTING.md`
- `SECURITY.md`
- **Repository-Prozess in Gitea**
- `.gitea/`
- Release-Notizen
- Issue- und PR-Triage
## Review-Regeln
Empfohlene Minimalregeln:
- Aenderungen an `compose.yaml`, `scripts/alanctl` oder Netz-Setup immer bewusst reviewen.
- Vor Merge von Infrastruktur-Aenderungen mindestens `./scripts/release-check` ausfuehren.
- Bei Aenderungen mit Betriebsfolgen zusaetzlich `./scripts/alanctl validate` und `./scripts/alanctl doctor` laufen lassen.
- Bei Update- oder Rollback-Aenderungen immer `CHANGELOG.md` und passende Doku mitziehen.
## CODEOWNERS-Hinweis
Dieses Repo enthaelt eine `CODEOWNERS`-Datei fuer Instanzen, die das unterstuetzen.
Falls deine Gitea-Version oder Konfiguration CODEOWNERS nicht automatisch auswertet, nutze diese Datei als dokumentierte Zustaendigkeitsmatrix und setze die Review-Regel organisatorisch ueber Pull Requests um.
## Praktischer Betrieb in kleinen Teams
Falls spaeter weitere Maintainer dazukommen, ist dieses Muster sinnvoll:
- `@johannes` als primaerer Owner fuer Runtime und Releases
- ein zweiter Owner fuer Dokumentation und Review
- sicherheitsrelevante Aenderungen nie ohne sichtbare Review-Notiz mergen
+38
View File
@@ -0,0 +1,38 @@
# Maintenance
## Regelmaessige Aufgaben
Woechentlich oder vor groesseren Aenderungen:
```bash
./scripts/alanctl status
./scripts/alanctl doctor
```
Monatlich:
```bash
./scripts/alanctl backup
docker image prune -f
```
Vor jedem Hermes-Update:
```bash
./scripts/alanctl backup
./scripts/alanctl update-hermes
```
## Repo-Pflege
- `.editorconfig`, `CODEOWNERS` und `docs/maintainers.md` synchron halten
- `CHANGELOG.md` aktuell halten
- veraltete Screenshots/Beispiele entfernen
- `.env.example` synchron zur Doku halten
- neue Ports, Netze und Volumes zentral in README und Architektur dokumentieren
## Regelmaessige Sicherheitspruefung
- oeffentliche Bindings gegen `127.0.0.1` und `br0` gegenpruefen
- `SECURITY.md` bei geaendertem Meldeprozess aktualisieren
- nach Netz- oder Mount-Aenderungen gezielt `doctor` und einen Test-Upgrade-Lauf ausfuehren
+44
View File
@@ -0,0 +1,44 @@
# Parallelbetrieb mit OpenClaw
## Empfehlung
Lass OpenClaw in einem **separaten Compose-Projekt** laufen.
Das Repo hier geht davon aus, dass OpenClaw bereits existiert oder separat gepflegt wird. Dadurch bleiben Updates, Logik und Fehlersuche voneinander getrennt.
## Regeln gegen Konflikte
- andere Host-Ports als Hermes verwenden
- eigenes Volume oder eigener Basisordner fuer OpenClaw
- eigener Compose-Projektname
- wenn moeglich kein gemeinsamer Schreibzugriff auf denselben Host-Pfad
- Shared-Netz nur verwenden, wenn es einen echten Grund gibt
- fuer Internetzugang idealerweise dasselbe Muster verwenden: **eigenes externes Macvlan-Netz auf `br0` oder bewusst dasselbe externe `br0`-Netz mit eigener IP**
## Sichere Defaults
Hermes expose't nur lokal:
- `127.0.0.1:18642/tcp` fuer API/Health
- `127.0.0.1:19119/tcp` fuer Dashboard, falls aktiviert
OpenClaw sollte auf einem **anderen** Host-Port laufen, z. B. `127.0.0.1:18080` oder `127.0.0.1:18081`, je nach Image.
## `br0`-Hinweis
Wenn OpenClaw wie Hermes ueber `br0` ins Netz soll, hast du zwei saubere Optionen:
1. **gleiches externes Docker-Netz** verwenden, mit eigener statischer IP je Container
2. **separates zweites Macvlan-Netz** auf demselben Parent `br0` anlegen
Option 1 ist einfacher. Option 2 ist strenger getrennt.
## Wann das Shared-Netz sinnvoll ist
Nur wenn sich OpenClaw und Hermes wirklich gegenseitig erreichen muessen, z. B. fuer einen lokalen Upstream-Endpoint oder Kontrollpfad. Ansonsten reicht die komplette Trennung.
## Beispiel fuer OpenClaw
Siehe `compose/openclaw.override.example.yaml`.
Das ist bewusst nur eine Vorlage, weil der OpenClaw-Docker-Oekosystem-Stand momentan fragmentiert ist und verschiedene Images unterschiedliche Environment-Variablen erwarten.
+79
View File
@@ -0,0 +1,79 @@
# Release-Prozess
## Ziel
Dieses Repo soll sich wie ein kleines Infrastrukturprodukt pflegen lassen:
- Aenderungen gesammelt entwickeln
- lokal validieren
- in Gitea taggen
- Releases mit klaren Upgrade-Hinweisen veroeffentlichen
## Versionsschema
Empfohlen: semantische Versionierung fuer das Repo.
- `MAJOR`: inkompatible Struktur- oder Betriebswechsel
- `MINOR`: neue Features oder neue Betriebsfaelle ohne harte Brueche
- `PATCH`: Fixes, Doku, sichere Defaults, kleinere Skriptanpassungen
Beispiele:
- `v0.1.0` erste stabile Struktur
- `v0.2.0` neue optionalen Dienste oder neue Netzvarianten
- `v0.2.1` Bugfix im Update-/Backup-Verhalten
## Maintainer-Ablauf
1. Feature- oder Fix-Branch bauen
2. lokal testen
3. `CHANGELOG.md` aktualisieren
4. bei Upgrade-Auswirkungen `docs/upgrade-policy.md` pflegen
5. Merge nach `main`
6. Release-Tag setzen
7. Release Notes in Gitea anlegen
## Lokale Checks vor einem Release
```bash
./scripts/release-check
./scripts/alanctl validate
./scripts/alanctl doctor
```
Optional auf einem echten Host:
```bash
./scripts/alanctl backup
./scripts/alanctl up --dashboard
./scripts/alanctl update-hermes
```
## Tagging
```bash
git checkout main
git pull --ff-only
git tag -a v0.1.1 -m "alan-agents-workstation v0.1.1"
git push origin main --tags
```
## Inhalt guter Release Notes
- Was ist neu?
- Was ist gefixt?
- Muss `.env` angepasst werden?
- Gibt es ein neues Netzwerk-/Volume-/Port-Verhalten?
- Ist ein manuelles Backup vor Upgrade empfohlen?
- Gibt es ein Rollback-Risiko bei State-Migrationen?
## Release-Text vorbereiten
Nutze `docs/release-template.md` als portable Vorlage fuer die Release-Beschreibung in Gitea.
Empfohlener Ablauf:
1. `./scripts/new-release <version>` ausfuehren
2. `CHANGELOG.md` finalisieren
3. Release-Text aus `docs/release-template.md` kopieren und auf den konkreten Stand anpassen
4. Tag pushen und Release in Gitea anlegen
+52
View File
@@ -0,0 +1,52 @@
# Release Template
Nutze diese Vorlage fuer neue Gitea-Releases.
---
## Summary
Kurze Zusammenfassung des Releases in 2-4 Saetzen.
## Added
-
-
## Changed
-
-
## Fixed
-
-
## Operational impact
- Muss `.env` angepasst werden? Ja/Nein
- Neue Ports, Volumes oder Netzwerke? Ja/Nein
- Neue manuelle Schritte nach dem Update? Ja/Nein
## Upgrade notes
1. Optional: `./scripts/alanctl doctor`
2. Optional: `./scripts/alanctl backup`
3. Update ausfuehren: `./scripts/alanctl update-hermes`
4. Health pruefen: `./scripts/alanctl status`
## Rollback notes
- Image-Rollback: `./scripts/alanctl rollback-hermes`
- State-Restore nur dann, wenn eine Datenmigration oder Konfigurationsaenderung Probleme macht
## Maintainer checklist
- [ ] `CHANGELOG.md` aktualisiert
- [ ] Doku angepasst
- [ ] `./scripts/release-check` erfolgreich
- [ ] `./scripts/alanctl validate` erfolgreich
- [ ] Release-Tag gesetzt
---
+36
View File
@@ -0,0 +1,36 @@
# Update-Strategie
Dieses Repo trennt bewusst zwischen **Pinning**, **Upgrade**, **Health-Pruefung** und **Rollback**.
## Prinzip
- `.env` enthaelt den gewuenschten `HERMES_TAG`
- `pin-hermes <tag>` aendert nur den Ziel-Tag
- `update-hermes [tag]` sichert zuerst den State und fuehrt dann das Upgrade aus
- `rollback-hermes` rollt auf den zuletzt als gesund gespeicherten Stand zurueck
## Empfohlener Ablauf
Vor einem groesseren Update:
```bash
./scripts/alanctl doctor
./scripts/alanctl backup
./scripts/alanctl update-hermes v0.9.3
```
Wenn der neue Stand nicht sauber hochkommt:
```bash
./scripts/alanctl rollback-hermes
```
Wenn das Problem in einer State-Migration liegt:
```bash
./scripts/alanctl restore ./backups/hermes/hermes-YYYYMMDD-HHMMSS.tar.gz
```
## Warum nicht dauerhaft latest
`latest` ist bequem, aber fuer einen reproduzierbaren Desktop- oder Homeserver-Betrieb unnoetig riskant. Ein fixer Tag macht Updates nachvollziehbar und Rollbacks deutlich einfacher.
+93
View File
@@ -0,0 +1,93 @@
# Upgrade-Policy
## Grundsatz
Upgrades sollen reversibel, dokumentiert und fuer eine einzelne Workstation realistisch bedienbar sein.
## Klassen von Aenderungen
### 1. Sicheres Patch-Upgrade
Beispiele:
- Doku-Updates
- Healthcheck-Feinschliff
- nicht-invasive Skriptkorrekturen
Erwartung:
- kein manueller Eingriff noetig
- normales `update-hermes` reicht
### 2. Operatives Minor-Upgrade
Beispiele:
- neue optionale Dienste
- neue `.env`-Variablen mit Default
- neue Docs/Tools
Erwartung:
- Release Notes lesen
- `git diff .env.example` gegen lokale `.env` pruefen
- ggf. neuen Key ergaenzen
### 3. Breakendes Upgrade
Beispiele:
- Netzwerknamen aendern
- Compose-Service-Namen aendern
- persistente Pfade aendern
- State-/Datenmigrationen mit Rueckwirkungsrisiko
Erwartung:
- Backup Pflicht
- Upgrade-Fenster bewusst planen
- Rollback testen
- Release Notes muessen eine explizite Migrationsanleitung enthalten
## Pflicht vor jedem geplanten Upgrade
```bash
./scripts/alanctl doctor
./scripts/alanctl backup
```
## Pflicht bei Repo-Upgrade
Wenn du das Repo selbst aktualisierst:
```bash
git fetch --tags
git checkout <ziel-tag-oder-branch>
./scripts/release-check
```
Danach erst:
```bash
./scripts/alanctl validate
./scripts/alanctl up
```
## Umgang mit `.env`
Die lokale `.env` ist betriebsrelevant und bleibt lokal.
Vor jedem Repo-Upgrade:
```bash
git diff HEAD~1 .env.example
```
oder allgemeiner:
```bash
git diff <alter-tag>..<neuer-tag> -- .env.example
```
Wenn neue Variablen eingefuehrt wurden, muessen diese in die lokale `.env` uebernommen werden.
## Rollback-Regel
Image-Rollback und State-Rollback sind getrennt zu betrachten.
- `rollback-hermes` setzt das letzte bekannte gute Image wieder ein
- bei problematischer Datenmigration muss zusaetzlich ein Backup-Archiv via `restore` zurueckgespielt werden