Skip to content
Joerg Bernau edited this page Oct 18, 2026 · 1 revision

Runner (Arbeitsumgebung für Modelle)

Der Runner gibt den Modellen eine echte Arbeitsumgebung: Dateien lesen, anlegen und gezielt ändern, suchen, Befehle ausführen, testen und nachbessern – wie ein Programmierwerkzeug, aber eingesperrt in einem Container auf deinem Rechner (PC oder Laptop im Heimnetz), nicht auf dem Server.

  • Der Container hat kein Netz (Ausnahme: Modus „Paketquellen“, s. u.) und nur einen flüchtigen Arbeitsbereich (/workspace im Arbeitsspeicher). Endet die Sitzung, bleibt auf dem Rechner nichts zurück.
  • Was das Modell erarbeitet, liegt als Arbeitsstand (git-Bundle mit der ganzen Historie) auf dem Server und wird mit der Datenbank gesichert. Jeder Werkzeugaufruf, der Dateien ändert, ist ein eigener Commit – jeder Stand ist zurückholbar.
  • Der Runner verbindet sich nur ausgehend mit MultiGPT (wss://<server>/runner/ws). Auf deinem Rechner bleibt kein Port offen. Jeder Zugriff läuft über MultiGPT: Rechte, Kontingent, Rückfragen und Audit-Log prüft immer der Server.

Wie startet der Container?

Gar nicht von Hand. Den Arbeitscontainer startet das Programm multigpt-runner, das als Dienst deines Nutzers läuft:

  1. Einmalig: Token erzeugen (Abschnitt 1), Programm installieren und koppeln (Abschnitt 2). Ab dann läuft multigpt-runner als systemd-User-Dienst und hält die Verbindung zu MultiGPT.
  2. Im Chat einen Arbeitsstand wählen (Abschnitt 3).
  3. Der erste Werkzeugaufruf des Modells startet die Sitzung: Der Runner zieht das Arbeits-Image (ghcr.io/beerlesklopfer/multigpt-runner-work, nur mit dem Digest, den der Server vorgibt), startet den Container nach der festen Vorlage (kein Netz, nur tmpfs, keine Rechte), lädt den Arbeitsstand hinein und führt die Werkzeuge darin aus.
  4. Nach 15 Minuten ohne Werkzeugaufruf (oder bei „Stopp“ im Chat) entfernt der Runner den Container wieder. Der Arbeitsstand ist dann schon auf dem Server.

Ob der Runner verbunden ist, zeigt die Seite Runner („verbunden“, Version, laufende Sitzungen). Läuft nichts, hilft systemctl --user status multigpt-runner und journalctl --user -u multigpt-runner -f.

Die Datei runner-images.txt im Release

Jedes Release auf GitHub enthält neben dem Paket die Datei runner-images.txt. Sie nennt die beiden Container-Images des Runners mit Digest (name:tag@sha256:…):

ghcr.io/beerlesklopfer/multigpt-runner:0.4.0@sha256:…        # Agent-Image (alter Python-Agent), nur für Quadlet
ghcr.io/beerlesklopfer/multigpt-runner-work:0.4.0@sha256:…   # Arbeits-Image: das braucht der Runner
  • Normalfall: nichts tun. Das Paket trägt dieselben Digests schon ein (/usr/share/multi-gpt/runner-images.env); die Seite Runner und der pair-Befehl enthalten das Arbeits-Image daraus. Ein Tag wie :0.4.0 allein genügt nicht – der Runner startet nur Images, deren Digest in MGPT_IMAGES steht, und der Server muss denselben Digest vorgeben.
  • Wofür die Datei dient: zum Gegenprüfen (stimmt der Digest auf der Seite Runner mit dem Release überein?), zum Vorab-Laden auf einem Rechner (podman pull <Zeile mit Digest>), und wenn der Server nicht aus dem Paket stammt: dann die Arbeits-Image-Zeile als RUNNER_WORK_IMAGE in die .env des Servers und als --images bei pair eintragen.
  • Das Arbeits-Image (multigpt-runner-work) ist die Umgebung, in der die Modelle arbeiten (Dateien, Befehle, Tests). Der Runner startet daraus pro Sitzung einen Container. Nur dieses Image brauchst du: bei pair --images und in MGPT_IMAGES.
  • Das Agent-Image (multigpt-runner) enthält den alten Python-Agenten, also das Programm, das die Verbindung zu MultiGPT hält und die Arbeitscontainer startet – nur eben als Container statt als Programm. Er läuft dann als Quadlet (Podman-eigene systemd-Datei, siehe „Ausweg: Runner als Container“) mit eingebundenem Podman-Socket. Das ist ein Ausweg für Systeme, auf denen sich das Programm multigpt-runner nicht installieren lässt, und entfällt, sobald der Python-Agent abgelöst ist. Wer den Runner wie oben als Programm (pair) installiert, kann diese Zeile ignorieren – das Image wird dann nie geladen. Wichtig: Beide Dinge heißen „multigpt-runner“ (Image und Programm), sind aber nicht dasselbe.
  • Fehlt die Datei in einem Release, lässt sich der Lauf „Runner-Images“ unter Actions von Hand mit dem Tag starten; er hängt sie nachträglich an.

Arbeits-Image von Hand ausprobieren

Zum Anschauen – mit denselben Einschränkungen, die der Runner setzt:

podman pull ghcr.io/beerlesklopfer/multigpt-runner-work:main
podman run --rm -it --network none --read-only --cap-drop ALL \
  --security-opt no-new-privileges --pids-limit 256 \
  --tmpfs /workspace:rw,size=256m,mode=0700,U --tmpfs /tmp:rw,size=64m \
  ghcr.io/beerlesklopfer/multigpt-runner-work:main bash

Das ist nur zum Ausprobieren; MultiGPT benutzt so gestartete Container nicht. :main ist der Stand von main, :latest bzw. :<version> der letzte Release.

Zum Testen in der Entwicklung (ohne TLS)

Für einen Entwicklungsserver ohne HTTPS:

  1. Runner-Dienst des Servers starten: .venv/bin/python manage.py runner_gateway (lauscht auf MULTI_GPT_RUNNER_BIND, Vorgabe 127.0.0.1:8001; für einen anderen Rechner im Heimnetz z. B. --bind 0.0.0.0:8001).
  2. In der .env des Servers das Arbeits-Image mit Digest eintragen, z. B. RUNNER_WORK_IMAGE=ghcr.io/beerlesklopfer/multigpt-runner-work:main-<commit>@sha256:… (steht in der Zusammenfassung des CI-Laufs „Runner-Images“), und den Server neu starten.
  3. Auf der Seite Runner einen Token erzeugen.
  4. Auf dem Rechner mit Podman koppeln, mit ws:// statt wss://:
    export MGPT_INSECURE_DEV=1
    printf '%s\n%s\n' "<token>" "<öffentlicher Schlüssel>" | \
      multigpt-runner pair --url ws://<server>:8001/runner/ws --images "<Image mit Digest>"
    Für die Unit Environment=MGPT_INSECURE_DEV=1 ergänzen (systemctl --user edit multigpt-runner).

MGPT_INSECURE_DEV nie auf der Produktion: Ohne TLS gehen Token und Werkzeugaufrufe im Klartext über das Netz.

Voraussetzungen

  • Recht „Runner nutzen“ in deiner Rolle (Startwerte: Verwalter und Erwachsene ja, Jugendliche und Gäste nein; ändert ein Verwalter im Admin unter Konten und Gruppen › Rollen).
  • Linux auf amd64 oder arm64 (PC, Laptop, Raspberry Pi mit 64-Bit-System) mit systemd.
  • Podman (rootless). Docker geht technisch auch, ist aber root-gleich und nicht empfohlen.
  • MultiGPT ist über HTTPS erreichbar (siehe nginx und TLS). Bei einem selbstsignierten Zertifikat hält der Runner dessen Fingerprint fest; die Kopplungsseite trägt ihn automatisch ein.

Der Runner ist ein eigenständiges Programm (multigpt-runner, in Rust geschrieben, eine Datei ohne Abhängigkeiten). Es läuft als systemd-Dienst deines Nutzers, nicht als root, und startet die Arbeitscontainer über deinen Podman-Socket – immer nach derselben festen Vorlage.

Einrichtung durch den Verwalter (Admin)

Einen Runner „legt“ der Verwalter nicht an: Jeder Nutzer koppelt seinen Rechner selbst (Abschnitt 1 und 2). Der Verwalter schafft die Voraussetzungen und legt die Grenzen fest. Im Admin gibt es dafür vier Stellen.

1. Server: Dienst, Schlüssel, Einstellungen

  • Das Paket installiert den Dienst multi-gpt-runner (WebSocket /runner/ws, nur lokal auf MULTI_GPT_RUNNER_BIND, Standard 127.0.0.1:8001) und den nginx-Block dafür. Prüfen: systemctl status multi-gpt-runner.
  • Der Installationsschlüssel des Servers entsteht bei der Installation. Anzeigen: sudo mgpt-ctl runner pubkey; fehlt er: sudo mgpt-ctl runner keygen. Mit --force ersetzen heißt, alle Runner müssen neu gekoppelt werden.
  • Einstellungen in der .env (nur bei Abweichungen vom Standard nötig; danach Dienste neu starten):
Einstellung Bedeutung
RUNNER_WORK_IMAGE Arbeits-Image mit Digest. Das Paket bringt es mit (runner-images.env); siehe runner-images.txt.
RUNNER_CA_SHA256 / RUNNER_TLS_CERT Nur bei selbstsigniertem Zertifikat: Fingerprint bzw. PEM-Datei; die Kopplungsseite trägt den Wert in den pair-Befehl ein.
RUNNER_PUBLIC_URL Adresse, unter der Zielsysteme den Server erreichen (setup_host); leer: erster https-Eintrag aus CSRF_TRUSTED_ORIGINS.
RUNNER_TOKEN_DAYS Gültigkeit neuer Kopplungs-Tokens in Tagen (Standard 90).
RUNNER_WORKSPACE_MAX_MB Größe je Arbeitsstand für Konten ohne Rolle (Standard 50); sonst gilt die Rolle.
RUNNER_PACKAGE_HOSTS Paketquellen für den Modus „Paketquellen“.
RUNNER_BROWSER_WS_URL Terminal im Browser; leer = gleiche Adresse (nginx). Nur in der Entwicklung ändern.
RUNNER_DIST_DIR Ordner mit den Runner-Programmen und dem signierten Katalog (Standard /usr/share/multi-gpt/runner).

2. Rechte und Grenzen: Konten und Gruppen › Rollen

Im Admin die Rolle öffnen; die Runner-Felder stehen gesammelt:

Feld Wirkung
Runner nutzen Mitglieder dürfen einen Runner koppeln und Modelle im Container arbeiten lassen. Ohne dieses Recht kann das Konto nicht koppeln, und ein verbundener Runner wird mit 4403 abgelehnt. Startwert: Verwalter und Erwachsene ja.
Fernzugriff (ssh/telnet) Werkzeuge ssh und telnet zu freigegebenen Hosts (siehe unten), immer mit Rückfrage.
Runner mit Netz Container erreicht das Netz einschließlich Heimnetz. Aus = kein Netz. Nur sparsam vergeben.
Paketquellen Container erreicht über einen Proxy nur die Hosts aus RUNNER_PACKAGE_HOSTS, kein Heimnetz. Gilt nicht, wenn „Runner mit Netz“ an ist.
CPUs, Arbeitsspeicher, Prozesse höchstens Obergrenzen je Container (Standard 1 CPU, 1024 MB, 256 Prozesse).
tmpfs /workspace, Scratchpad, Container-Schicht (MB) Größe von Arbeitsbereich (512), Scratchpad (1024) und beschreibbarer Schicht im Modus „Paketquellen“ (4096).
Arbeitsstände je Konto / Größe je Arbeitsstand Anzahl (10) und Höchstgröße des git-Bundles (50 MB).

Die Laufzeit pro Monat steht nicht in der Rolle, sondern unter Kosten und Abrechnung › Abrechnungskonten › Runner-Laufzeit (siehe „Laufzeit-Kontingent“).

3. Der Runner als MCP-Server (Chat › MCP-Server)

Für die Chat-Schleife ist ein gekoppelter Runner ein MCP-Server wie jeder andere, mit Transport runner. MultiGPT legt den Eintrag „Runner ()“ selbst an, sobald ein Konto zum ersten Mal einen Token erzeugt bzw. koppelt – der Verwalter muss und soll ihn nicht von Hand anlegen.

  • Der Eintrag gehört genau einem Konto. Nur dieses darf ihn benutzen (und nur mit dem Recht „Runner nutzen“); auch ein Superuser kann den Runner eines anderen nicht verwenden. Er braucht deshalb auch nicht in der Rolle unter „erlaubte MCP-Server“ zu stehen.
  • Im Admin unter Chat › MCP-Server sieht man ihn mit Status und Werkzeugliste, kann ihn deaktivieren (aktiv aus) oder die Werkzeuge einstufen. Einstufung, Rückfrage und Freigabe je Modell gelten wie bei jedem MCP-Server, siehe MCP-Server.
  • Die Werkzeuge kommen über die Verbindung des gekoppelten Programms. Ist der Runner getrennt, kann der Eintrag nicht arbeiten; dann zuerst den Dienst auf dem Rechner prüfen (Fehlersuche).

4. Der Admin-Bereich „Runner (Container auf dem Browser-Rechner)“

Eintrag Was der Verwalter tut
Runner-Tokens Ansehen (ohne Token oder Hash) und widerrufen (trennt den Runner sofort). Anlegen können nur Nutzer selbst bzw. mgpt-ctl runner token create <Konto>.
Runner, Arbeitsstände, Sitzungen, Audit Nur lesen: Metadaten, keine Inhalte, keine Argumente, keine Ausgaben.
Hosts Geräte für ssh/telnet und setup_host anlegen: Name, Protokoll, Adresse, Benutzer, Zugang (SSH-Schlüssel bzw. Passwort, wird verschlüsselt gespeichert und nie wieder angezeigt), SSH-Host-Schlüssel bestätigen, Freigabe für Rollen und Konten. Telnet überträgt alles im Klartext – nur für alte Geräte im Heimnetz.
Dienste Neue Dienste aus einem signierten Dienstkatalog erscheinen als „nicht eingestuft“ und werden nicht angeboten, bis der Verwalter sie einstuft (lesen / Dateien ändern / Befehl / Datei in den Chat / Fernzugriff / Einrichtung) und auf „freigegeben“ setzt. „Sperren“ nimmt einen Dienst wieder weg.

Verwalter-Befehle auf dem Server

sudo mgpt-ctl runner token create <Konto> --name Laptop --expires 90d   # Token (einmal angezeigt)
sudo mgpt-ctl runner token list [<Konto>]
sudo mgpt-ctl runner token revoke <ID oder mgrt_…>
sudo mgpt-ctl runner pubkey                                               # Schlüssel für `pair`

Reihenfolge für die erste Inbetriebnahme

  1. systemctl status multi-gpt-runner nginx – beide laufen.
  2. Rolle: Runner nutzen (und nach Bedarf Netz/Pakete, Grenzen) setzen.
  3. Nutzer koppeln ihren Rechner (Abschnitt 1 und 2); der MCP-Eintrag entsteht dabei von selbst.
  4. Seite Runner zeigt verbunden; im Admin unter Chat › MCP-Server steht der Eintrag „Runner ()“ auf online.
  5. Im Chat Arbeitsstand wählen, erster Werkzeugaufruf (Abschnitt 3).

1. Token erzeugen

  1. Im Kontomenü (oben rechts) Runner öffnen.
  2. Name eingeben (z. B. „Laptop“), Gültigkeit wählen, Token erzeugen.
  3. Der Token (mgrt_…) ist nur jetzt sichtbar. Darunter stehen die Befehle zum Einrichten, die Eingabe für pair (Zeile 1 Token, Zeile 2 öffentlicher Schlüssel des Servers) und die fertige Unit-Datei – alles mit Kopierknopf.

Ein Token gehört zu genau einem Rechner. Er lässt sich jederzeit widerrufen; ein verbundener Runner wird dann sofort getrennt. MultiGPT speichert nur einen Hash des Tokens.

2. Programm installieren und koppeln (Linux)

Programm von MultiGPT herunterladen (empfohlen)

MultiGPT liefert das Programm selbst aus – das Zielsystem braucht weder Internet noch Rust. Auf der Seite Runner stehen die Programme für amd64 und arm64 mit Prüfsumme; die Prüfsummen sind mit dem Schlüssel des jeweiligen Releases signiert (SHA256SUMS, SHA256SUMS.sig). Herunterladen geht nur angemeldet bzw. mit einem Kopplungs-Token.

systemctl --user enable --now podman.socket   # Podman-Socket des Nutzers
loginctl enable-linger $USER                   # Dienst läuft auch ohne Anmeldung
cd ~/Downloads && ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
sha256sum --ignore-missing -c <<'SUMS'         # Prüfsummen von der Seite „Runner“
<sha256>  multigpt-runner-linux-amd64
<sha256>  multigpt-runner-linux-arm64
SUMS
install -D -m 0755 multigpt-runner-linux-$ARCH ~/.local/bin/multigpt-runner
~/.local/bin/multigpt-runner --version

Alternative für Entwickler: cargo install

Mit Rust (ab 1.88) direkt aus dem Quellbaum von MultiGPT:

cargo install --locked --path runner-rs/multigpt-runner   # legt ~/.cargo/bin/multigpt-runner an
install -D -m 0755 ~/.cargo/bin/multigpt-runner ~/.local/bin/multigpt-runner

Ein selbst gebautes Programm trägt keinen signierten Dienstkatalog. Der Server bietet seine Werkzeuge deshalb nur an, wenn der Katalog eines Releases signiert mitgegeben wird (MGPT_CATALOG_FILE, MGPT_CATALOG_SIG_FILE, MGPT_CATALOG_KEY) oder in einer Entwicklungsinstallation (DEBUG mit RUNNER_ACCEPT_UNSIGNED). Für den Alltag das Programm von MultiGPT nehmen.

Koppeln und als Dienst starten

Den Befehl von der Seite Runner ausführen, danach die Eingabe für pair einfügen und mit Strg+D abschließen:

~/.local/bin/multigpt-runner pair --url https://mgpt.example \
    --images ghcr.io/…/multigpt-runner-work@sha256:… [--ca-sha256 <Fingerprint>]

Die Angaben im Beispiel sind Platzhalter – mgpt.example und … nicht wörtlich übernehmen, sondern den fertigen Befehl von der Seite Runner kopieren. Die Parameter:

Angabe Bedeutung
--url Adresse deines MultiGPT-Servers, so wie du sie im Browser öffnest, z. B. https://mgpt.familie.example (mit Port, falls nicht 443). Der Runner ergänzt /runner/ws selbst und verbindet sich per wss://. Sie muss vom Runner-Rechner aus erreichbar sein (kein localhost). ws:// ist nur mit MGPT_INSECURE_DEV=1 erlaubt. Wird als MGPT_URL in die Unit geschrieben.
--images Arbeits-Image mit Digest (registry/name@sha256:…), das der Runner starten darf. Ein Tag allein wird abgelehnt. Mehrere Images durch Leerzeichen getrennt in Anführungszeichen. Den Wert gibt die Seite Runner vor; er steht auch in runner-images.txt des Releases (Zeile multigpt-runner-work). Wird als MGPT_IMAGES in die Unit geschrieben.
--ca-sha256 Nur bei selbstsigniertem Zertifikat: SHA-256-Fingerprint (64 Hex-Zeichen) des Server-Zertifikats. Der Runner vertraut dann genau diesem Zertifikat. Bei einem normalen, öffentlich ausgestellten Zertifikat weglassen. Die Seite Runner trägt den Wert automatisch ein. Wird als MGPT_CA_SHA256 geschrieben.
--no-start Optional: nur Dateien und Unit anlegen, den Dienst nicht starten (zum Beispiel erst config.env bearbeiten). Danach systemctl --user daemon-reload && systemctl --user enable --now multigpt-runner.
Eingabe (stdin) Zeile 1: Token (mgrt_…), Zeile 2: öffentlicher Schlüssel des Servers. Nach dem Befehl einfügen und mit Strg+D abschließen. Der Token steht so nie im Shell-Verlauf.

pair legt in ~/.config/multigpt-runner/ den Token (token, nur für dich lesbar) und den öffentlichen Schlüssel des Servers (server.pub, schreibgeschützt) ab, schreibt die User-Unit ~/.config/systemd/user/multigpt-runner.service und startet den Dienst. Der Token steht nie in einem Befehl (Shell-Verlauf), in der Unit-Datei oder im Container.

Konfigurationsdatei des Runner-Agents

~/.config/multigpt-runner/config.env (bei XDG entsprechend $XDG_CONFIG_HOME/multigpt-runner/config.env). pair legt eine kommentierte Vorlage an und erhält eine vorhandene Datei bei erneuter Kopplung. Die Kopplungsseite bietet zusätzlich vor pair den Schritt „Persönliche Konfiguration anlegen“: Der erzeugte Befehl schreibt die Vorlage auf dem Runner-Rechner mit Modus 0600, wenn sie fehlt. Der systemd-User-Dienst liest alle dort gesetzten MGPT_*-Einstellungen; sie überschreiben die Vorgaben in der Unit. Ohne Datei gelten die bisherigen Vorgaben. Beispiel:

MGPT_EXPOSE_HOST=192.168.xxx.yyy
MGPT_EXPOSE_BIND=0.0.0.0
MGPT_HOSTNAME=WS-NAME

Format KEY=value, kein export. Für Dateipfade absolute Pfade verwenden; ~, $HOME und %h werden innerhalb der Datei nicht ersetzt. Anschließend systemctl --user restart multigpt-runner. Für bestehende Installationen einmal per systemctl --user edit multigpt-runner ergänzen:

[Service]
EnvironmentFile=-%h/.config/multigpt-runner/config.env

Falls die Datei noch fehlt, als Benutzer des Runners anlegen und bearbeiten:

mkdir -p ~/.config/multigpt-runner
touch ~/.config/multigpt-runner/config.env
chmod 600 ~/.config/multigpt-runner/config.env
nano ~/.config/multigpt-runner/config.env

Nach dem erstmaligen Ergänzen der Unit:

systemctl --user daemon-reload
systemctl --user restart multigpt-runner
systemctl --user status multigpt-runner

Bei späteren Änderungen an config.env genügt der Neustart. systemctl --user cat multigpt-runner zeigt die Unit samt Drop-ins und damit, ob EnvironmentFile eingebunden ist. Mit einem eigenen XDG-Konfigurationsordner den Pfad in der Unit und den Befehlen entsprechend anpassen.

Bei direktem Start des Programms ohne systemd werden weiterhin die Prozess-Umgebungsvariablen verwendet; die Datei wird durch systemd geladen. Die Datei enthält keine Token oder privaten Schlüssel, sondern nur Einstellungen und Pfade. Token und öffentlicher Server-Schlüssel bleiben in token und server.pub. Eine kommentierte Vorlage liegt im Quellcode unter runner-rs/multigpt-runner/systemd/config.env.example.

Unterstützte Einstellungen

Die Datei kann alle folgenden MGPT_*-Werte setzen. Die bei der Kopplung erzeugte Unit liefert bereits Server-Adresse, Image-Freigabe, Secret-Pfade, Podman-Socket und Scratchpad-Pfade. In config.env müssen daher nur gewünschte Abweichungen stehen.

Einstellung Bedeutung und Vorgabe
MGPT_URL Server-Adresse als https://host oder wss://host/runner/ws; bei pair vorgegeben.
MGPT_CA_SHA256 SHA-256-Fingerprint des Server-Zertifikats, bei selbst signierten Zertifikaten; ohne Angabe reguläre Zertifikatsprüfung.
MGPT_IMAGES Erlaubte Arbeits-Images mit Digest; mehrere durch Leerzeichen getrennt, z. B. MGPT_IMAGES="registry/image@sha256:… registry/other@sha256:…". Die Freigabe des Servers muss ebenfalls passen.
MGPT_HOSTNAME Anzeigename des Rechners beim Verbinden; ohne Angabe der Rechnername.
MGPT_EXPOSE_HOST Name oder IP für die native Web-Adresse, ohne Schema, Port oder Pfad; z. B. 192.168.xxx.yyy. Ohne Angabe ermittelt der Agent die lokale Adresse seiner Verbindung zum Server.
MGPT_EXPOSE_BIND Bindung der exportierten Ports: 0.0.0.0 (Vorgabe, im Heimnetz erreichbar) oder 127.0.0.1 (nur auf dem Runner-Rechner). EXPOSE_HOST ändert nur die angezeigte Adresse, diese Einstellung bestimmt die Erreichbarkeit.
MGPT_TOKEN_FILE Absoluter Pfad zur Token-Datei; bei pair im Konfigurationsordner als token.
MGPT_SERVER_KEY_FILE Absoluter Pfad zum öffentlichen Installationsschlüssel des Servers; bei pair im Konfigurationsordner als server.pub.
MGPT_PODMAN_SOCKET Podman-Socket; die User-Unit setzt /run/user/<UID>/podman/podman.sock. Ohne Unit-Vorgabe verwendet das Programm /run/podman.sock.
MGPT_SCRATCH_DIR Lokaler Scratchpad-Ordner aus Sicht des Agents; die User-Unit setzt ~/MultiGPT/Scratch.
MGPT_SCRATCH_HOST_DIR Derselbe Ordner aus Sicht von Podman; bei nativem Agent normalerweise identisch zu MGPT_SCRATCH_DIR.
MGPT_CATALOG_FILE Optionaler Dienstkatalog als Datei statt des eingebauten Katalogs.
MGPT_CATALOG_SIG_FILE Signaturdatei des optionalen Dienstkatalogs.
MGPT_CATALOG_KEY ID des Signaturschlüssels, 16 Hex-Zeichen; bei signiertem externem Katalog erforderlich.
MGPT_LABELS Zusätzliche Container-Labels als "k=v k2=v2"; normalerweise nicht erforderlich.
MGPT_INSECURE_DEV 1 erlaubt unverschlüsselte ws://-Verbindungen für Entwicklung; standardmäßig aus.
MGPT_ENGINE podman (Vorgabe). fake ist ausschließlich in Testbauten mit Feature fake-engine und MGPT_INSECURE_DEV=1 verfügbar.

Beispiel

MGPT_HOSTNAME=WS-NAME
MGPT_EXPOSE_HOST=192.168.xxx.yyy
MGPT_EXPOSE_BIND=0.0.0.0

Bei einer Sitzung auf dem ersten Portpaar zeigt serve damit http://192.168.xxx.yyy:24080/; HTTPS liegt auf Port 24443. Weitere gleichzeitige Sitzungen verwenden die nächsten freigegebenen Portpaare. Eine bereits vom LLM formulierte Chatantwort wird durch die Konfigurationsänderung nicht umgeschrieben; nach dem Neustart eine neue Sitzung starten und serve erneut aufrufen.

Dienst prüfen

Prüfen: systemctl --user status multigpt-runner bzw. journalctl --user -u multigpt-runner. Auf der Seite Runner steht der Rechner nach wenigen Sekunden als verbunden.

Die Unit-Datei (Auszug; der vollständige Inhalt steht auf der Seite Runner, von Hand anlegen geht auch):

[Service]
ExecStart=%h/.local/bin/multigpt-runner
Environment=MGPT_URL=https://mgpt.example
Environment=MGPT_TOKEN_FILE=%h/.config/multigpt-runner/token
Environment=MGPT_SERVER_KEY_FILE=%h/.config/multigpt-runner/server.pub
Environment=MGPT_PODMAN_SOCKET=%t/podman/podman.sock
Environment=MGPT_IMAGES=ghcr.io/…/multigpt-runner-work@sha256:…
EnvironmentFile=-%h/.config/multigpt-runner/config.env
Restart=on-failure
RestartPreventExitStatus=2 3

Exit-Codes: 2 = Einstellungen fehlen oder sind falsch (z. B. Token- oder Schlüsseldatei fehlt, Image ohne Digest). 3 = der Server hat abgelehnt (Token ungültig oder widerrufen, Recht fehlt, Verbindung ersetzt, Protokollversion passt nicht) oder ein Rahmen trug keine gültige Signatur dieses Servers. In beiden Fällen startet systemd den Dienst nicht neu – erst neu koppeln (pair mit neuem Token). Bei Netzproblemen versucht es der Runner selbst wieder (1 s, 2 s, 4 s … bis 60 s).

Neuer Token: auf der Seite Runner erzeugen und pair erneut ausführen (ersetzt Token und Schlüssel); den alten Token widerrufen.

Mehrere Umgebungen (z. B. dev und prod)

Ein Runner koppelt mit genau einem MultiGPT-Server. Für Entwicklung und Produktion braucht jede Umgebung ihren eigenen Runner, mit eigenem Token (Token und Schlüssel gehören zu einem Server; der Schlüssel eines anderen Servers wird mit Close-Code 4498 abgelehnt).

Nicht auf demselben Benutzerkonto zweimal koppeln. pair schreibt immer in dieselben Stellen (~/.config/multigpt-runner/, multigpt-runner.service); die zweite Kopplung ersetzt die erste still. Außerdem teilen sich beide Programme Podman des Benutzers: Jeder Runner übernimmt beim Start die Arbeitscontainer, die er vorfindet (Label multigpt.runner=1), und sein Server stoppt, was er nicht kennt – ein zweiter Runner im selben Podman würde also die Sitzungen des ersten beenden. Auch das Vorschau-Portpaar (24080–24089) ist nur einmal je Rechner vorhanden.

Sauber getrennt sind:

  1. Zwei Rechner (empfohlen): je einer für dev und prod. Das ist ohnehin die sichere Trennung – ein Entwicklungsmodell soll nicht auf dem Produktionsrechner arbeiten.
  2. Zwei Benutzerkonten auf einem Rechner, jedes mit eigenem Podman, eigenem Linger und eigener Kopplung:
sudo useradd -m mgpt-dev
sudo loginctl enable-linger mgpt-dev
sudo machinectl shell mgpt-dev@            # Anmeldung mit eigener User-Sitzung (nicht su/sudo -u)
# dort: Programm installieren und mit der Adresse und dem Token des dev-Servers koppeln

Die Vorschau-Ports teilen sich beide Benutzer; ein bereits belegter Port wird übersprungen, insgesamt gibt es zehn. Die Image-Freigabe (--images) ist je Umgebung getrennt, denn dev und prod haben meist verschiedene Arbeits-Images und Digests.

Im Chat erkennt man die Umgebung am Eintrag „Runner ()“ der jeweiligen MultiGPT-Instanz; MGPT_HOSTNAME (z. B. WS-NAME-dev) macht die Rechner auf der Seite Runner unterscheidbar.

Raspberry Pi und andere arm64-Geräte

  • Ein 64-Bit-System ist nötig (Raspberry Pi OS 64 bit bzw. Debian arm64, Pi 3/4/5). Prüfen: uname -m muss aarch64 melden; auf 32-Bit-Systemen läuft das Programm nicht.
  • Podman aus den Paketquellen: sudo apt install podman (Debian 12/13, Raspberry Pi OS).
  • Das Programm multigpt-runner-linux-arm64 von der Seite Runner nehmen; der Rest ist wie oben.
  • Grenzen für RAM und Prozesse setzt Podman über cgroups v2. Meldet die Sitzung „Grenzen weichen ab“, fehlt dem Kernel der Speicher-Controller: in /boot/firmware/cmdline.txt cgroup_enable=memory ergänzen und neu starten.
  • Der erste Start lädt das Arbeits-Image (je nach Leitung einige Minuten).

Ein Gerät, auf dem gearbeitet werden soll (z. B. ein Pi in der Werkstatt), wird so ein eigener Runner deines Kontos – mit eigener Kopplung, eigenen Rechten und eigenem Audit. Befehle laufen auch dort nur im Container nach der festen Vorlage.

Zielsystem aus dem Chat einrichten (setup_host)

Statt von Hand kann ein Modell ein freigegebenes Gerät einrichten: Werkzeug setup_host (fragt immer nach). Voraussetzungen: Recht „Runner-Hosts nutzen“ und ein vom Verwalter freigegebener Host mit SSH-Schlüssel (Admin Runner › Hosts). Der Runner verbindet sich aus einem kurzlebigen Hilfscontainer per ssh, bestimmt die Architektur, lädt das Programm von MultiGPT (Prüfsumme wird verglichen), installiert es nach ~/.local/bin und koppelt mit einem frischen Token nur für diesen Aufruf. Schlägt die Einrichtung fehl, widerruft der Server diesen Token sofort. Zugang und Token sieht das Modell nie.

Windows und macOS

Das Programm gibt es nur für Linux. Unter Windows geht der Linux-Weg in WSL2 mit systemd, unter macOS in einer Linux-VM (z. B. Podman machine, podman machine ssh). Der Server muss von dort erreichbar sein (gleiche Adresse wie im Browser).

Ausweg: Runner als Container (Quadlet)

Solange es den bisherigen Python-Agenten noch gibt, zeigt die Seite Runner unter „Ausweg“ zusätzlich eine Quadlet-Datei (Agent als Container mit eingebundenem Podman-Socket, Token und Schlüssel als Podman-Secrets). Neue Installationen bitte mit dem Programm oben. Die Quadlet-Datei startet das Agent-Image multigpt-runner@sha256:… (Zeile 1 in runner-images.txt); es verwaltet seinerseits Arbeitscontainer aus dem Arbeits-Image.

3. Im Chat arbeiten

  1. Arbeitsstand anlegen: Runner › Arbeitsstände, „Neuer Arbeitsstand“ (z. B. „Bildschirmschoner“).

  2. Im Chat erscheint unter den Eingabeoptionen der Bereich Runner: Arbeitsstand wählen und den Rückfrage-Modus:

    Modus Dateien ändern Befehle
    fragen mit Rückfrage mit Rückfrage
    Änderungen automatisch ohne Rückfrage mit Rückfrage
    alles automatisch (Vorgabe ohne Netz) ohne Rückfrage ohne Rückfrage

    setup_host und telnet fragen immer nach, egal welcher Modus.

    Daneben die Auswahl Scratch (Ablage für Zwischenergebnisse unter /scratch): im Container (flüchtig, Vorgabe) oder auf diesem Rechner (Ordner ~/MultiGPT/Scratch/<id>/). Nach MultiGPT kommt daraus nur, was das Modell ausdrücklich mit publish als Anhang veröffentlicht. Die Auswahl gilt ab der nächsten Sitzung.

  3. Ein werkzeugfähiges Modell wählen und die Aufgabe beschreiben. Der erste Werkzeugaufruf startet die Sitzung (Container); das dauert beim ersten Mal etwas länger (Image laden).

  4. Über dem Eingabefeld erscheinen die Aufgabenliste des Modells und die Knöpfe:

    • Terminal: eine Shell im Container, direkt im Browser (auch für Programme mit Eingabe). Strg+Umschalt+F6 verlässt das Terminal mit der Tastatur.
    • Vorschau: HTML-Seiten, die das Modell mit serve bereitstellt, in einem abgeschotteten Rahmen – oder über „In neuem Tab öffnen“.
    • Audit: alle Werkzeugaufrufe der Sitzung.

Nach 100 Werkzeugrunden fragt der Chat, ob weitergearbeitet werden soll.

Pakete nachladen (Modus „Paketquellen“)

Ohne Netz kann das Modell nur mit dem arbeiten, was im Arbeits-Image steckt (bash, git, Python, Node). Mit dem Rollenrecht „Paketquellen“ darf es zusätzlich Pakete nachladen – vor allem mit apt, außerdem mit pip, npm, cargo und von GitHub –, erreicht dabei aber nur fest freigegebene Paketquellen, nie das Heimnetz oder beliebige Seiten.

Wer darf? Recht „Paketquellen“ in der Rolle (Startwerte: Verwalter und Erwachsene ja, Jugendliche und Gäste nein; Admin unter Konten und Gruppen › Rollen). Ist auch „Runner mit Netz“ an, geht das freie Netz vor (dann gibt es kein apt_install). Ohne beide Rechte bleibt das Netz aus. Über API-Keys gilt der Modus nur mit demselben Rollenrecht. Der Rückfrage-Modus „alles automatisch“ bleibt erlaubt.

  • Im Chat steht im Bereich Runner der Schalter „Paketquellen“ (nur mit dem Rollenrecht sichtbar, Vorgabe an). Umschalten geht nur, solange keine Sitzung läuft; er gilt ab der nächsten Sitzung.
  • In einer Sitzung mit Paketquellen gibt es kein setup_host und kein telnet. Für die Einrichtung eines Zielsystems bzw. telnet den Schalter ausschalten.
  • Der Modus braucht ein aktuelles multigpt-runner (Werkzeug apt_install im signierten Dienstkatalog). Ältere Runner bekommen ihn nie angeboten; die Sitzung startet dann ohne Netz.

apt: nur über das Werkzeug apt_install

Das Modell ruft apt_install mit einer Liste von Debian-Paketen auf, z. B. ["jq", "ripgrep"]. Der Runner führt dann im Container als root nur apt-get update (bei Bedarf) und apt-get install -y --no-install-recommends <pakete> aus:

  • Paketnamen werden streng geprüft (Kleinbuchstaben, Ziffern, + . -, höchstens 20 je Aufruf); Optionen, Pfade oder Shell-Zeichen werden abgewiesen.
  • Die Shell des Modells bleibt Nutzer 1000: apt-get/dpkg selbst aufzurufen scheitert an fehlenden Rechten, sudo gibt es nicht – und auch ein nachinstalliertes sudo wirkt nicht (no-new-privileges, keine setuid-Programme).
  • apt_install zählt wie bash als Befehl (Rückfrage je nach Modus) und steht im Audit-Log.

Über Sitzungen hinweg: Die installierten apt-Pakete stehen in .mgpt/apt-packages im Arbeitsstand. Startet später eine neue Sitzung mit diesem Arbeitsstand, installiert der Runner sie automatisch nach. Wer ein Paket nicht mehr braucht, entfernt die Zeile aus der Datei.

pip, npm, cargo, GitHub

Diese Werkzeuge arbeiten als Nutzer 1000 und installieren in den Arbeitsstand unter /workspace – ohne root:

Werkzeug Beispiel landet in
pip python3 -m venv .venv && .venv/bin/pip install requests .venv/
npm npm install left-pad, npx http-server node_modules/
cargo cargo build (nach apt_install(["cargo"])) target/
git git clone https://github.com/… Ordner im Arbeitsstand

.venv, node_modules und target trägt der Runner automatisch in .gitignore ein: Sie gehören nicht ins Bundle (das bleibt klein) und werden in einer neuen Sitzung neu installiert – am besten über requirements.txt bzw. package.json im Arbeitsstand.

Der Proxy und was gesperrt ist

Der Arbeitscontainer hat auch in diesem Modus keinen direkten Weg nach außen und kein DNS. Er hängt nur an seinem internen Sitzungsnetz; dort steht ein Proxy (der Relay-Container der Sitzung), den pip, npm, cargo, git und apt über HTTP_PROXY/HTTPS_PROXY benutzen. Der Proxy lässt nur diese Hosts durch (Einstellung RUNNER_PACKAGE_HOSTS des Servers, signiert an den Runner übergeben):

deb.debian.org, security.debian.org, pypi.org, files.pythonhosted.org, registry.npmjs.org, github.com, codeload.github.com, objects.githubusercontent.com, index.crates.io, static.crates.io

Abgewiesen werden:

  • alle anderen Hosts (z. B. example.com) und Unterdomänen, die nur so aussehen;
  • IP-Literale (http://1.1.1.1/, IPv6, Dezimalschreibweise) – der Proxy nimmt nur Namen;
  • Heimnetz und Rechner selbst (192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, Loopback, Link-Local) – auch, wenn ein freigegebener Name dorthin aufgelöst würde;
  • andere Ports (nur GET über Port 80 und CONNECT zu Port 443);
  • jeder Versuch am Proxy vorbei (direkte Verbindung, eigenes DNS) – es gibt keine Route.

Fällt der Proxy aus, ist das Netz zu (fail closed).

Grenze der Container-Schicht: Weil das Wurzeldateisystem in diesem Modus beschreibbar ist, misst der Runner die Größe der Schicht bei jedem Heartbeat. Die Grenze legt die Rolle fest („Runner: Container-Schicht (MB)“, Vorgabe 4096 MB); wird sie überschritten, endet die Sitzung. Die Schicht ist flüchtig und mit dem Container weg – der Arbeitsstand bleibt.

Webserver und Ports (lighttpd)

Im Arbeits-Image ist lighttpd installiert, ausschließlich für statische Dateien (HTML, JS, CSS, Bilder); es gibt keine serverseitige Ausführung, keine Verzeichnislisten und keinen Zugriff auf .git.

Im Container Am Rechner
8080 (http) 24080 Standardexport für „80“
8443 (https) 24443 Standardexport für „443“, selbst signiertes Zertifikat

Die Ports 80 und 443 kann der Nutzer im Container ohne Rechte nicht binden; deshalb 8080/8443 im Container. Laufen mehrere Sitzungen gleichzeitig, bekommt die nächste das Paar 24081/24444, dann 24082/24445 usw. bis 24089/24452.

  • Starten: das Werkzeug serve (optional mit Verzeichnis) oder im Terminal mgpt-serve (--dir site). Beide starten lighttpd mit http und https.
  • Eigene Konfiguration: lighttpd -D -f <datei>; eine fertige Standardkonfiguration (statisch, /workspace, Port 8080) liegt unter /etc/lighttpd/lighttpd.conf.
  • Wer sieht es? Standardmäßig bindet der Runner die Ports an 0.0.0.0, also im ganzen Heimnetz ohne Anmeldung. Auf den Rechner selbst beschränkt es MGPT_EXPOSE_BIND=127.0.0.1 in der Unit des Runners. Die Vorschau im Chat läuft unabhängig davon über MultiGPT (mit Token und abgeschottet).
  • Ein anderer Server funktioniert auch, solange er auf 8080 (bzw. 8443) lauscht, z. B. python3 -m http.server 8080 --directory site.

Seite „Runner“: Live-Status und Audit

Die Seite zeigt (alle 5 s aktualisiert) deine Runner, die laufenden und letzten Sitzungen und die Laufzeit im Monat. Je Sitzung gibt es ein Audit-Log: Werkzeug, gekürzte Argumente (Geheimnisse entfernt), Exit-Code, Dauer – nie Ausgaben. Einträge werden nach API_AUDIT_DAYS Tagen (Standard 90) gelöscht.

Verwalter sehen im Admin nur Metadaten (Runner, Sitzungen, Größe der Arbeitsstände), keine Inhalte, keine Argumente von Werkzeugaufrufen und keine Ausgaben anderer Konten.

Laufzeit-Kontingent

Container-Minuten zählen auf das Abrechnungskonto „Runner-Laufzeit“ (siehe Kosten und Budgets):

  • Kontingent je Rolle bzw. Person in Minuten pro Monat (Person vor Rolle), leer = unbegrenzt. Startwert für Erwachsene: 600 Minuten.
  • Gezählt wird nach der Uhr des Servers, solange der Runner die Sitzung als laufend meldet (Heartbeat alle 30 s; Ausfälle zählen nicht). Am Sitzungsende wird auf die angefangene Minute aufgerundet.
  • Ab 80 % erscheint ein Hinweis (Kopfzeile, Seite „Runner“). Bei 100 % stoppt der Server alle Sitzungen des Kontos, neue starten erst im nächsten Monat. Die Arbeitsstände bleiben erhalten.
  • Mein Verbrauch und die Familienübersicht zeigen die Minuten.

Sicherheit in Kürze

  • Drei Schichten: Wer – der Token weist deinen Rechner aus (auf dem Server nur als Hash, widerrufbar). Was – der Runner bietet nur Dienste aus einem signierten Dienstkatalog an (Signatur des Releases; verändert oder unsigniert → keine Werkzeuge, Eintrag im Audit). Wo – Befehle laufen nur im Container nach fester Vorlage.

  • Jeder Rahmen des Servers ist mit dem Schlüssel dieser Installation signiert und an die Verbindung gebunden; der Runner nimmt nichts anderes an (sonst Ende mit Exit-Code 3). Token, Programm und Schlüssel liegen außerhalb der Sandbox – das Modell kann sie weder lesen noch ändern.

  • Zugänge für telnet und setup_host kommen nur vom Server, je bestätigtem Aufruf, und liegen nur in einem kurzlebigen Hilfscontainer – nie im Arbeitscontainer.

  • Arbeitscontainer: nur das freigegebene Image (mit Digest), rootless, ohne Capabilities, ohne Host-Verzeichnisse, mit Grenzen für CPU, RAM, Prozesse und Ausgabe; Netz aus (ohne DNS).

  • Modus „Paketquellen“ (nur mit Rollenrecht): Die feste Vorlage wird nur für den Arbeitscontainer und nur so weit gelockert, wie apt_install es braucht – beschreibbare, flüchtige Container-Schicht und genau die Capabilities CHOWN, DAC_OVERRIDE, FOWNER, FSETID, SETUID, SETGID (rootless nur im eigenen User-Namespace, also ohne Rechte auf dem Rechner). no-new-privileges, Nutzer 1000 für die Shell, keine Host-Namespaces, keine fremden Netze und keine Mounts bleiben. Netz nur über den Proxy mit Positivliste, kein Heimnetz. Runner und Testvektoren lehnen jede andere Kombination ab (z. B. beschreibbare Schicht ohne diesen Modus, weitere Capabilities, privileged, ein zweites Netz).

  • Keine Geheimnisse des Rechners im Container (kein Home-Verzeichnis, keine SSH-Schlüssel, bereinigte Umgebung).

  • Vorschau: nur über MultiGPT mit zufälligem Sitzungs-Token im Pfad, in einem Rahmen mit sandbox und strenger CSP (keine Netzverbindungen, kein Zugriff auf MultiGPT), ohne Verzeichnislisten.

  • Alles, was aus dem Container kommt, gilt als nicht vertrauenswürdig.

Das vollständige Bedrohungsmodell steht in docs/Implementierung.md, Abschnitt 5.

Fehlersuche

Schritt für Schritt, wenn der Runner nicht „verbunden“ wird

Meldet das Journal (journalctl --user -u multigpt-runner -f) wiederholt Verbindung fehlgeschlagen: E/A (connection refused) und neuer Versuch in … s, dann kommt der Runner nicht bis zum Server: Unter der Adresse in MGPT_URL nimmt niemand Verbindungen an. Das ist kein Fehler von Token, Schlüssel oder Podman – die werden erst nach dem Verbinden geprüft. Der Runner versucht es mit wachsenden Pausen (bis 60 s) endlos weiter; ein Neustart des Dienstes setzt die Pause auf 1 s zurück.

  1. Welche Adresse benutzt der Runner? systemctl --user cat multigpt-runner | grep MGPT_URL (und config.env, die die Unit überschreiben kann). Die Adresse muss vom Runner-Rechner aus erreichbar sein – ein Name, der nur auf dem Server selbst auflöst, localhost oder 127.0.0.1 ist falsch.
  2. Antwortet der Server? curl -sI https://<server>/ auf dem Runner-Rechner. Ohne Antwort: Name, Port 443, Firewall und nginx prüfen. Bei selbstsigniertem Zertifikat meldet curl einen Zertifikatsfehler; das ist ok, solange MGPT_CA_SHA256 den Fingerprint von der Seite Runner trägt.
  3. Läuft der Runner-Dienst auf dem Server? Er ist ein eigener Dienst neben dem Webdienst: systemctl status multi-gpt-runner (Paket) bzw. manage.py runner_gateway (Entwicklung). nginx reicht location = /runner/ws an MULTI_GPT_RUNNER_BIND (Standard 127.0.0.1:8001) weiter. Ist nginx erreichbar, der Dienst aber nicht, endet die Verbindung mit einem HTTP-Fehler (502), nicht mit „connection refused“.
  4. Entwicklungsserver ohne TLS? Dann ws://<server>:8001/runner/ws mit MGPT_INSECURE_DEV=1 (siehe oben) – und MULTI_GPT_RUNNER_BIND auf eine Adresse setzen, die vom Runner-Rechner erreichbar ist (--bind 0.0.0.0:8001), nicht 127.0.0.1.
  5. Adresse korrigiert? pair mit der richtigen --url erneut ausführen oder MGPT_URL in config.env setzen, dann systemctl --user restart multigpt-runner. Die Seite Runner zeigt den Rechner nach wenigen Sekunden als verbunden.

Die Versionsangabe im Journal (MultiGPT-Runner <Version> startet) ist die Version des Runner-Programms, nicht die des Servers. ~/.local/bin/multigpt-runner --version zeigt sie auch.

Erst Überblick verschaffen

Diese Befehle auf dem Runner-Rechner sagen in der Regel schon, wo es hakt:

systemctl --user status multigpt-runner        # läuft er? seit wann? letzter Exit-Code?
journalctl --user -u multigpt-runner -n 50     # die letzten Meldungen
systemctl --user cat multigpt-runner           # tatsächliche Unit samt Drop-ins
systemctl --user status podman.socket          # Podman-Socket des Nutzers
ls -l ~/.config/multigpt-runner/               # token, server.pub, config.env vorhanden?
podman info >/dev/null && echo "podman ok"
loginctl show-user $USER | grep Linger         # Linger=yes: Dienst läuft auch ohne Anmeldung

Mehr Einzelheiten im Journal: systemctl --user edit multigpt-runner, dort [Service] / Environment=RUST_LOG=debug eintragen und den Dienst neu starten. Danach wieder entfernen. Auf dem Server: systemctl status multi-gpt-runner nginx und journalctl -u multi-gpt-runner -n 50.

Der Reihe nach: wo bricht es ab?

Zwischen Klick im Chat und laufendem Werkzeug liegen fünf Stufen. Die erste, die nicht klappt, ist das Problem:

Stufe Prüfung Wenn nicht
1. Programm startet systemctl --user status multigpt-runner zeigt active (running) Dienst startet nicht
2. Podman erreichbar Journal ohne „Engine nicht erreichbar“ Podman
3. Verbindung zum Server Journal ohne „Verbindung fehlgeschlagen“ Abschnitt oben („connection refused“ u. a.)
4. Server nimmt den Runner an Seite Runner zeigt verbunden Server lehnt ab
5. Sitzung und Werkzeuge Chat: erster Werkzeugaufruf läuft Sitzung startet nicht

Dienst startet nicht oder endet sofort

Das Journal nennt die Ursache in einer Zeile mit „Einstellungen:“. Häufige Fälle:

Meldung oder Zeichen Ursache und Abhilfe
Unit … could not be found / not-found pair wurde nie (erfolgreich) ausgeführt oder lief unter einem anderen Benutzer. Als der Benutzer, der den Runner betreiben soll, pair ausführen; danach systemctl --user daemon-reload.
status=203/EXEC ExecStart zeigt auf ein fehlendes oder nicht ausführbares Programm. ls -l ~/.local/bin/multigpt-runner; ggf. neu installieren (install -D -m 0755 …). Die Unit nutzt den Pfad, mit dem pair aufgerufen wurde.
status=2 / „MGPT_IMAGES ist leer“ Keine Image-Freigabe: pair ohne --images oder MGPT_IMAGES leer überschrieben. --images mit Digest nachtragen (Zeile multigpt-runner-work aus runner-images.txt).
„Token- oder Schlüsseldatei …“ ~/.config/multigpt-runner/token oder server.pub fehlt bzw. ist nicht lesbar. pair erneut ausführen, mit der Eingabe (Token und Schlüssel, Strg+D).
„Image ohne Digest“ --images bzw. MGPT_IMAGES enthält nur ein Tag. Es muss name@sha256:… sein.
„MGPT_URL muss mit https:// oder wss:// beginnen“ Adresse ohne Schema oder mit http://. ws:///http:// nur mit MGPT_INSECURE_DEV=1 (nur Entwicklung).
„Unverschlüsselte Verbindung nur mit MGPT_INSECURE_DEV=1“ Wie oben: https verwenden oder in der Entwicklung die Variable setzen.
Dienst hält nach status=2/3 an und startet nicht neu Gewollt (RestartPreventExitStatus=2 3). Ursache beheben, dann systemctl --user restart multigpt-runner.
Änderung in config.env ohne Wirkung Dienst nicht neu gestartet, EnvironmentFile fehlt in der Unit (systemctl --user cat …), KEY=value mit export, ~ oder $HOME im Wert (werden nicht ersetzt) oder Tippfehler im Namen.
Dienst stoppt beim Abmelden loginctl enable-linger $USER fehlt.
Failed to connect to bus bei systemctl --user (per SSH oder sudo) Keine User-Sitzung. Direkt als der Benutzer anmelden oder export XDG_RUNTIME_DIR=/run/user/$(id -u) setzen; nicht mit sudo zu einem anderen Benutzer wechseln.

Podman und der Socket

Der Runner steuert Podman über den Socket des Nutzers (/run/user/<UID>/podman/podman.sock). Das Journal meldet „Engine nicht erreichbar“, wenn das nicht klappt.

  1. systemctl --user enable --now podman.socket und systemctl --user status podman.socket.
  2. ls -l /run/user/$(id -u)/podman/podman.sock – existiert der Socket? Gehört er dir?
  3. podman info als derselbe Benutzer: Fehler hier sind Podman-Fehler, nicht Runner-Fehler (häufig: fehlende subuid/subgid-Einträge in /etc/subuid, /etc/subgid für rootless; Abhilfe laut Podman-Dokumentation: sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER, danach podman system migrate).
  4. Docker statt Podman? Der Runner erwartet die Podman-Schnittstelle. Läuft nur Docker, ist der Socket nicht kompatibel – Podman installieren.
  5. Eigener Socket-Pfad: MGPT_PODMAN_SOCKET in config.env (absolut). Ohne Angabe nimmt das Programm /run/podman.sock, die von pair erzeugte Unit setzt den Nutzer-Socket.
  6. Nach Änderungen: systemctl --user restart multigpt-runner.

Server lehnt ab (Close-Codes)

Das Journal zeigt „Server beendet die Verbindung: …“ oder Verbindung beendet (<Code>). Bei den ersten fünf Codes verbindet sich der Runner nicht mehr von selbst, der Dienst endet mit Code 3.

Code Bedeutung Abhilfe
4401 Token ungültig, abgelaufen oder widerrufen Auf der Seite Runner neuen Token erzeugen, pair erneut ausführen. Tippfehler beim Einfügen? Zeile 1 muss mit mgrt_ beginnen.
4403 Kein Recht „Runner nutzen“ Verwalter vergibt das Recht der Rolle (Admin › Konten und Gruppen › Rollen).
4409 Ersetzt durch neue Verbindung Derselbe Token wird auf zwei Rechnern benutzt (oder zwei Diensten). Pro Rechner ein eigener Token.
4426 Protokollversion nicht unterstützt Programm und Server passen nicht zusammen: Programm von diesem Server neu herunterladen (oder Server aktualisieren).
4498 Signatur des Servers ungültig server.pub gehört nicht zu diesem Server (z. B. Server neu installiert oder mgpt-ctl runner keygen --force). Neuen Token erzeugen, pair mit der neuen Eingabe wiederholen.
4400 Protokollfehler Meist Versionsmischung oder ein Proxy, der Daten verändert; Programm neu laden, nginx-Block /runner/ws prüfen.
4402 Kontingent erschöpft Monatskontingent Runner-Laufzeit erhöhen oder warten.
4408 Keine Anmeldung Der Runner hat sich nach dem Verbinden nicht rechtzeitig gemeldet: Podman antwortet zu langsam (siehe oben) oder der Rechner ist überlastet.
4413 Rahmen zu groß Selten; Programm und Server aktualisieren, Fehler melden.
4429 Zu viele Anfragen Der Runner verbindet sich zu oft (Schleife?). Warten; prüfen, ob mehrere Dienste laufen.
1006, 1011, 1012, 1013, 1001 Verbindung abgebrochen bzw. Server startet neu Normal bei Neustart des Servers. Der Runner verbindet sich mit Pause (1 s … 60 s) selbst neu. Bleibt es dauerhaft: nginx und multi-gpt-runner auf dem Server prüfen.

Zertifikatsprobleme zeigen sich als Verbindungsfehler, nicht als Close-Code:

  • „Zertifikat des Servers passt nicht zum festgehaltenen Fingerprint“: Zertifikat wurde erneuert. Neuen Fingerprint von der Seite Runner übernehmen: pair --ca-sha256 … oder MGPT_CA_SHA256 in config.env ändern.
  • „invalid peer certificate“ / „UnknownIssuer“: Selbstsigniertes oder privates Zertifikat ohne MGPT_CA_SHA256. Fingerprint eintragen (Seite Runner), nicht das Zertifikat im System „vertrauen“.
  • „certificate not valid for name“: --url nennt einen Namen, der nicht im Zertifikat steht (z. B. IP statt Name). Den Namen aus dem Zertifikat verwenden.
  • „certificate expired“ oder falsche Uhrzeit: timedatectl auf dem Runner-Rechner prüfen.

Sitzung startet nicht (Image, Ports, Kontingent)

Der Runner ist verbunden, aber der erste Werkzeugaufruf im Chat scheitert oder dauert ewig.

Meldung oder Zeichen Ursache und Abhilfe
„Arbeits-Image konnte nicht gezogen werden“ Zuerst von Hand testen: podman pull <Image@sha256:…>. unauthorized/denied: Paket in ghcr.io ist nicht öffentlich (einmalig auf „public“ stellen). no such host / Timeout: Runner-Rechner kommt nicht ins Internet (Proxy, DNS, Firewall). manifest unknown: Digest stimmt nicht – aus runner-images.txt desselben Releases übernehmen. Der erste Start lädt mehrere hundert MB und dauert entsprechend.
„Image ohne Digest wird nicht gezogen“ Die Image-Freigabe des Servers (RUNNER_WORK_IMAGE) oder MGPT_IMAGES trägt nur ein Tag. Digest eintragen.
Server und Runner nennen verschiedene Images MGPT_IMAGES (Runner) und RUNNER_WORK_IMAGE (Server) müssen auf denselben Digest zeigen, sonst startet keine Sitzung. Nach einem Server-Update pair erneut ausführen oder MGPT_IMAGES anpassen.
„Sitzung … nicht gestartet: …“ Die Meldung nach dem Doppelpunkt nennt den Grund (Podman-Fehler, zu wenig Speicher, Port belegt). Mit podman ps -a und podman logs <Container> nachsehen.
„Laufzeit-Kontingent ausgeschöpft“ Siehe Tabelle weiter unten.
„Der Arbeitsstand wird gerade in einer anderen Sitzung benutzt“ Eine Sitzung je Arbeitsstand; andere beenden oder 15 Minuten Leerlauf abwarten.
Werkzeuge hängen, nichts passiert podman ps --filter label=multigpt.runner=1 – läuft ein Arbeitscontainer? Rechner im Ruhezustand? Im Chat „Stopp“, dann neu starten. Hilft das nicht: podman rm -f des Containers und Dienst neu starten.
Ports 24080/24443 nicht erreichbar Läuft serve in der aktuellen Sitzung? Firewall des Runner-Rechners (ss -ltnp | grep 240); MGPT_EXPOSE_BIND=127.0.0.1 macht sie nur lokal erreichbar; MGPT_EXPOSE_HOST falsch gesetzt zeigt eine falsche Adresse an, ändert aber die Erreichbarkeit nicht. Ein weiterer Runner im selben Netz belegt dieselben Ports nur auf seinem eigenen Rechner.
Browser meldet Zertifikatswarnung auf Port 24443 Gewollt: das Zertifikat ist selbstsigniert. Warnung bestätigen oder Port 24080 nehmen (nur im Heimnetz).
Scratchpad „lokal“ leer oder nicht beschreibbar MGPT_SCRATCH_DIR/MGPT_SCRATCH_HOST_DIR sind absolute Pfade und zeigen auf einen Ordner, den dein Benutzer beschreiben darf (Standard ~/MultiGPT/Scratch). Unter SELinux kann ein anderes Verzeichnis nötig sein.
Paketinstallation (apt_install, pip, npm) scheitert Nur im Modus „Paketquellen“ und nur über den Proxy; Hosts außerhalb der Positivliste sind gesperrt (siehe Abschnitt „Der Proxy und was gesperrt ist“).

Von vorn anfangen

Bleibt die Ursache unklar, ist das saubere Neukoppeln meist der schnellste Weg:

systemctl --user disable --now multigpt-runner
rm -f ~/.config/systemd/user/multigpt-runner.service
rm -f ~/.config/multigpt-runner/token ~/.config/multigpt-runner/server.pub   # config.env bleibt
systemctl --user daemon-reload
podman ps -a --filter label=multigpt.runner=1                                # Reste?
podman rm -f $(podman ps -aq --filter label=multigpt.runner=1) 2>/dev/null

Dann auf der Seite Runner den alten Token widerrufen, einen neuen erzeugen und den pair-Befehl von der Seite ausführen. Die Arbeitsstände liegen auf dem Server; auf dem Rechner geht dabei nichts verloren.

Was man bei einer Fehlermeldung mitschicken sollte

Ohne Token und Schlüssel (die nie weitergeben):

~/.local/bin/multigpt-runner --version
systemctl --user cat multigpt-runner | grep -v -i token
journalctl --user -u multigpt-runner -n 100 --no-pager
podman --version; uname -m; cat /etc/os-release | head -3

und auf dem Server journalctl -u multi-gpt-runner -n 100 --no-pager.

Meldungen und Abhilfe (Kurzfassung)

Meldung Ursache und Abhilfe
„Kein Runner verbunden“ Agent läuft nicht oder erreicht den Server nicht: systemctl --user status multigpt-runner, Adresse und Zertifikat prüfen.
Journal: „connection refused“, „neuer Versuch in … s“ Unter MGPT_URL nimmt niemand Verbindungen an (falsche Adresse, Port, Firewall oder Dienst nicht gestartet): siehe Schritt für Schritt.
Dienst endet mit Code 2 Einstellungen fehlen oder sind falsch (journalctl --user -u multigpt-runner nennt die Ursache, z. B. Token- oder Schlüsseldatei fehlt): pair erneut ausführen.
Dienst endet mit Code 3 Token ungültig, abgelaufen oder widerrufen, Rolle ohne Recht oder Signatur des Servers ungültig (z. B. Server neu installiert): neuen Token erzeugen, pair erneut ausführen.
Runner verbunden, aber keine Werkzeuge Dienstkatalog unsigniert, verändert oder von einem zu alten Release (die Seite Runner zeigt den Zustand): Programm von MultiGPT neu herunterladen.
„Fingerprint passt nicht“ im Log Das Zertifikat des Servers hat sich geändert: Fingerprint auf der Seite Runner prüfen und pair mit neuem --ca-sha256 ausführen.
„Laufzeit-Kontingent ausgeschöpft“ Monatskontingent verbraucht; ein Verwalter kann es im Admin unter Kosten und Abrechnung › Abrechnungskonten › Runner-Laufzeit erhöhen.
„Der Arbeitsstand wird gerade in einer anderen Sitzung benutzt“ Nur eine Sitzung je Arbeitsstand: die andere Sitzung beenden (oder warten, bis der Leerlauf sie stoppt).
Terminal: „Zu viele offene Terminals“ Je Server-Prozess sind höchstens vier Terminals offen; ein anderes schließen.

Clone this wiki locally