Eigener Server und Sicherheit
Runner und selbst hosten
Installier setup-runner auf deinem eigenen Docker-Host, verbinde ihn mit einem Workspace und halte ihn abgesichert und aktuell.
Auf dieser Seite
- Was du brauchst
- Heimserver mit einem Code verbinden
- Runner installieren und registrieren
- 1. Runner im Dashboard anlegen
- 2. Binärdatei auf den Host bringen
- 3. Starten
- 4. Nach einem Neustart weiterlaufen lassen
- So verbindet er sich
- Flags
- Registry-Mirror
- Subnetz-Pool
- Den Host absichern
- Aktualisieren
- Runner entfernen
- Fehlersuche
Ein Runner ist der Rechner, auf dem deine Apps laufen. Setup entscheidet, was laufen soll; der Runner lädt die Images, startet die Container und behält sie im Blick. Solange du keinen eigenen Rechner verbindest, laufen Apps in der Setup Cloud, einem gemeinsamen Runner, den Setup betreibt.
Dein eigener Runner kann ein NAS, ein Heimserver oder ein VPS sein. Darauf läuft nur ein Programm, setup-runner. Es spricht mit Docker auf diesem Rechner und baut die Verbindung zu Setup selbst auf. Du öffnest keine Ports, und deine Apps samt Daten bleiben auf deiner Hardware.
Was du brauchst
- Einen Linux-Rechner mit Docker Engine 25 oder neuer, dem Compose-v2-Plugin und BuildKit (
docker buildx). - Ausgehendes HTTPS von diesem Rechner zu deinem Setup-Server.
- Die Admin-Rolle im Workspace. Nur Admins können Runner hinzufügen oder ändern.
- Empfohlen: gVisor für stärkere Isolation, siehe Den Host absichern.
Heimserver mit einem Code verbinden
Verbinde nur ein Gerät, das Tag und Nacht läuft. Apps darauf gibt es nur, solange es läuft: Ein Teamkalender auf einem NAS, das nachts schläft, ist bis zum Morgen für alle weg. Für Apps, die andere nutzen, ist ein Server in deinem eigenen Cloud Konto meist der bessere Ort.
- Öffne Runner und wähl Heimserver verbinden. Setup zeigt einen Kopplungscode wie
KX7P-4MQ2, die Setup Adresse und einen QR Code. Der Code gilt einmal, 15 Minuten lang. - Installiere auf dem Heimserver die App Setup Runner und gib in ihren Einstellungen die Setup Adresse und den Kopplungscode ein. Es gibt Pakete für Unraid, TrueNAS, CasaOS, Umbrel, Runtipi, den Synology Container Manager, eine einfache Docker Compose Datei und ein Skript für den ersten Start eines Raspberry Pi.
- Der Runner tauscht den Code gegen ein eigenes Token, legt es in seinem Datenordner ab und verbindet sich. Der Dialog zeigt Verbunden mit dem Namen des Geräts. Gib ihm einen Namen und sag Setup, ob es Tag und Nacht läuft; Setup nutzt die Antwort, wenn es vorschlägt, wo eine App laufen soll.
Ohne Kommandozeile passiert alles im Installationsformular des Stores. Mit einer Shell geht dasselbe mit setup-runner pair <code> --server <adresse> und danach setup-runner run.
Was die App darf: Sie steuert Docker auf diesem Gerät über den Docker Socket, und das ist dasselbe wie volle Kontrolle über das Gerät. Sie startet deine Apps als eigene Container neben sich, gibt ihre Ports aus einem Bereich frei, den du wählst (standardmäßig 20000 bis 20999), und hält für Setup keine Ports offen, weil sie nur nach außen verbindet.
Zum Entfernen löschst du in Setup zuerst die Apps darauf und dann den Runner, deinstallierst danach die App im Store und löschst ihren Datenordner.
Die Pakete sind noch in keinem Store und das Image ist nicht veröffentlicht. Heute funktioniert das also mit einem Runner Image, das du selbst baust (make image in apps/runner).
Runner installieren und registrieren
1. Runner im Dashboard anlegen
Öffne Runner (/dashboard/runners oder /dashboard/<workspace>/runners für eine Organisation), wähl Runner hinzufügen, gib ihm einen Namen wie home-nas und wähl Runner erstellen. Der Dialog zeigt das Runner-Token. Es beginnt mit srt_ und erscheint nur einmal, weil Setup davon nur einen Hash speichert.
2. Binärdatei auf den Host bringen
setup-runner ist eine einzelne Go-Binärdatei ohne externe Abhängigkeiten. Bau sie aus apps/runner im Setup-Quellcode; für einen anderen Rechner setzt du GOOS und GOARCH (zum Beispiel GOOS=linux GOARCH=arm64).
cd apps/runner
go build -o bin/setup-runner ./cmd/setup-runner
sudo install -m 0755 bin/setup-runner /usr/local/bin/setup-runner
setup-runner doctor --server https://setup.exampledoctor prüft Docker, die Isolation, den freien Speicherplatz, das Datenverzeichnis, den Portbereich und ob dein Server antwortet. Beheb jede Zeile mit FAIL. Der Tab Docker im Dialog zeigt ein Image, das noch nicht veröffentlicht ist; nimm die Binärdatei.
3. Starten
Der Tab Binärdatei enthält diesen Befehl mit deiner Adresse und deinem Token:
setup-runner run --server https://setup.example --token srt_…Auf einem NAS oder Heimserver gibst du zusätzlich die Adresse an, unter der andere den Rechner erreichen, damit die App-Links funktionieren:
setup-runner run --server https://setup.example --token srt_… \
--public-host 192.168.1.20 --bind-ip 192.168.1.20Der Dialog wechselt von „Wartet, bis sich der Runner verbindet …“ zu „home-nas ist verbunden.“ Wähl Fertig.
4. Nach einem Neustart weiterlaufen lassen
Speicher das als /etc/systemd/system/setup-runner.service, mit deiner Adresse und deinem Token, und aktivier den Dienst:
[Unit]
Description=Setup runner
Requires=docker.service
After=docker.service network-online.target
[Service]
ExecStart=/usr/local/bin/setup-runner run --server https://setup.example --token srt_…
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload && sudo systemctl enable --now setup-runnerDer Dienst läuft als root mit dem Datenverzeichnis /var/lib/setup-runner, und andere Benutzer auf dem Rechner können das Token in der Unit-Datei lesen. Eine sicherere Variante steht unter Den Host absichern.
So verbindet er sich
Der Runner baut nur ausgehende HTTPS-Verbindungen auf und funktioniert deshalb hinter NAT und Firewalls. Er holt Jobs per Long-Polling (bis zu 30 Sekunden pro Anfrage) und schickt alle 15 Sekunden einen Heartbeat; nach 90 Sekunden ohne Kontakt zeigt das Dashboard ihn als Offline. Setup speichert vom Token nur einen SHA-256-Hash. Ein Runner übernimmt nur Apps aus seinem eigenen Workspace. Ist er gestoppt, laufen die Apps weiter, aber Setup sieht und ändert sie erst wieder, wenn er sich neu verbindet.
Flags
Jedes Flag liest auch eine Umgebungsvariable. Bei Schaltern bedeutet jeder nicht leere Wert „an“.
| Flag | Variable | Standard | Wirkung |
|---|---|---|---|
--server | SETUP_SERVER | Pflicht | Deine Setup-Adresse |
--token | SETUP_RUNNER_TOKEN | Pflicht | Das Runner-Token |
--public-host | SETUP_PUBLIC_HOST | localhost | Host oder IP in App-Links |
--bind-ip | SETUP_BIND_IP | alle Interfaces | Host-IP, auf der App-Ports lauschen |
--port-range | SETUP_PORT_RANGE | 20000-20999 | Host-Ports für Apps |
--max-jobs | SETUP_MAX_JOBS | 2 | Parallele Jobs, 1 bis 64 |
--data-dir | SETUP_DATA_DIR | /var/lib/setup-runner als root unter Linux, sonst ~/.local/state/setup-runner | Status, Compose-Dateien, Sicherungen |
--docker-context | DOCKER_CONTEXT | aktueller Kontext | Welcher Docker-Host genutzt wird |
--runtime | SETUP_RUNTIME | auto | Wählt gVisor, dann Kata, dann runc; runc schaltet das ab |
--allow-published-ports | SETUP_ALLOW_PUBLISHED_PORTS | aus | Erlaubt Rezepten, rohe TCP- oder UDP-Ports zu veröffentlichen |
--registry-mirror | SETUP_REGISTRY_MIRROR | keiner | Docker-Hub-Mirror, siehe unten |
--subnet-pool | SETUP_SUBNET_POOL | keiner | IPv4-Bereich für App-Netze, siehe unten |
--no-log-shipping | SETUP_NO_LOG_SHIPPING | aus | Keine App-Logs an Setup schicken |
--tofu-image, --ingress-image, --helper-image und --go-builder-image ersetzen die fest gepinnten Hilfs-Images für Hosts mit eigener Registry. setup-runner run -h listet alle Flags.
Registry-Mirror
Docker Hub begrenzt anonyme Downloads pro IP-Adresse, und ein Heimnetz hinter einer einzigen öffentlichen Adresse stößt schnell an diese Grenze.
setup-runner run --server https://setup.example --token srt_… \
--registry-mirror mirror.gcr.iomirror.gcr.io ist Googles öffentlicher Docker-Hub-Cache; jeder Pull-Through-Mirror funktioniert (host[:port][/path]). Der Runner holt Docker-Hub-Images zuerst vom Mirror und taggt sie unter ihrem ursprünglichen Namen, die Rezepte bleiben also unverändert. Klappt das nicht, lädt er direkt von Docker Hub. Andere Registries und per Digest gepinnte Images nutzt er immer direkt. Basis-Images in den FROM-Zeilen von Builds kommen weiterhin von Docker Hub, weil BuildKit sie selbst holt; dafür trägst du registry-mirrors in daemon.json ein.
Subnetz-Pool
Jede App nutzt bis zu vier Docker-Netze. Ein Docker-Daemon mit Standardeinstellungen vergibt etwa 30 davon, und ein Host mit weiteren Compose-Projekten kann sie aufbrauchen: „all predefined address pools have been fully subnetted“.
setup-runner run --server https://setup.example --token srt_… \
--subnet-pool 10.213.0.0/16Der Runner gibt dann jedem App-Netz ein eigenes /27 aus diesem Bereich (ein /16 reicht für 2.048), überspringt Blöcke, die sich mit bestehenden Netzen überschneiden, und gibt sie wieder frei, wenn die App entfernt wird. Jobs für externe Dienste nutzen denselben Pool. Er muss IPv4 und /27 oder größer sein. Wähl einen Bereich, den dein LAN und VPN nicht nutzen.
Den Host absichern
Jeden Container und jedes App-Netz sichert der Runner ohne Konfiguration ab; was er durchsetzt, steht im Sicherheitsmodell. Die folgenden Schritte gehen weiter. Sie sind optional, und der Runner wendet keinen davon an. Teste sie vorher: Firewall-Regeln können andere Container abschneiden.
gVisor installieren. Unter runc teilen sich Container den Kernel des Hosts. gVisor gibt ihnen einen eigenen Kernel im User-Space, und der Runner nutzt ihn automatisch. Unter Debian oder Ubuntu:
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" \
| sudo tee /etc/apt/sources.list.d/gvisor.list
sudo apt-get update && sudo apt-get install -y runsc
sudo runsc install
sudo systemctl restart dockerImages, die stark auf io_uring oder Direct I/O setzen, verhalten sich darunter manchmal anders; --runtime runc nimmt einen Runner aus.
Builds aus deinem LAN fernhalten. Build-Schritte (RUN) nutzen Dockers Standard-Bridge und erreichen so auch dein Netz. Diese Regeln verwerfen neue Verbindungen von docker0 in private Bereiche und lassen die App-Netze in Ruhe:
sudo iptables -I DOCKER-USER -i docker0 -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
for net in 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10 169.254.0.0/16; do
sudo iptables -A DOCKER-USER -i docker0 -d "$net" -j DROP
doneWeniger nach außen zeigen. Binde die Ports mit --bind-ip an die LAN-Adresse, schütz den Portbereich mit einer Firewall und lass --allow-published-ports aus, solange keine App rohe Ports braucht.
Dem Runner einen eigenen Benutzer geben. Zugriff auf Docker ist so gut wie root. Nimm einen eigenen Benutzer in der Gruppe docker, auf einem Rechner oder einer VM, die sonst nichts tut. Das Datenverzeichnis enthält Compose-Dateien mit aufgelösten Secrets und die Sicherungen; leg es auf eine verschlüsselte Platte. Verschieb das Token nach /etc/setup-runner.env, lesbar nur für root:
SETUP_SERVER=https://setup.example
SETUP_RUNNER_TOKEN=srt_…[Unit]
Description=Setup runner
After=docker.service
Requires=docker.service
[Service]
User=setup-runner
EnvironmentFile=/etc/setup-runner.env
ExecStart=/usr/local/bin/setup-runner run --data-dir /var/lib/setup-runner
Restart=on-failure
RestartPreventExitStatus=3
[Install]
WantedBy=multi-user.targetDer Benutzer setup-runner muss Eigentümer von /var/lib/setup-runner sein. Exit-Status 3 heißt, dass Setup das Token abgelehnt hat; ein Neustart bringt dann nichts.
Aktualisieren
Der Runner aktualisiert sich nicht selbst. Bau die neue Binärdatei und tausch sie aus:
sudo systemctl stop setup-runner
sudo install -m 0755 bin/setup-runner /usr/local/bin/setup-runner
sudo systemctl start setup-runner
setup-runner versionBeim Stoppen nimmt der Runner keine neuen Jobs an und gibt laufenden bis zu fünf Minuten. systemd wartet standardmäßig nur 90 Sekunden; erhöh TimeoutStopSec, wenn lange Jobs fertig werden sollen.
Token erneuern am Runner erzeugt ein neues Token, das alte funktioniert sofort nicht mehr. Trag das neue in die Unit oder die Umgebungsdatei ein und starte den Dienst neu.
Runner entfernen
- Entferne zuerst seine Apps im Dashboard, damit Setup ihre Container, Volumes und externen Ressourcen löscht.
- Wähl Löschen und dann Runner löschen. Laufen noch Apps darauf, deaktiviert Setup den Runner nur und behält ihre Einträge. In beiden Fällen funktioniert das Token nicht mehr.
- Stopp den Dienst.
lslistet Apps, die noch im Datenverzeichnis stehen;destroyentfernt alles, was das Label eines Slugs trägt.
sudo systemctl disable --now setup-runner
sudo setup-runner ls
sudo setup-runner destroy <slug>Jobs für externe Dienste hinterlassen das Volume setup-tofu-plugin-cache und das Netz setup-provision-egress. Lösch das Datenverzeichnis zuletzt; darin liegen die Sicherungen.
Fehlersuche
- Verbindet sich nie. Führ
setup-runner doctor --server https://setup.exampleaus und liesjournalctl -u setup-runner. - Beendet sich mit Status 3. Das Token wurde erneuert, oder der Runner wurde gelöscht oder deaktiviert. Nimm ein neues Token.
- „cannot reach the Docker daemon“. Docker läuft nicht, der Benutzer ist nicht in der Gruppe
docker, oder--docker-contextstimmt nicht. - App-Links zeigen auf localhost. Setz
--public-host. - „all predefined address pools have been fully subnetted“. Nimm
--subnet-pool. - Pulls laufen ins Rate-Limit von Docker Hub. Nimm
--registry-mirror. - Der Runner zeigt „Gehärtete Container“. Er hat weder gVisor noch Kata gefunden. Installier gVisor.