SSD Nodes Learn 🎉 VPS ab $5.50/Monat
Anleitungen Matt ConnorVon Matt Connor

OpenBot-KI-Mitarbeiter selbst auf einem VPS hosten

Betreiben Sie OpenBot mit Gateway, eigenem Container und Chromium-Browser pro Bot. Erfahren Sie, wie Richtlinien Aktionen prüfen und wie viel RAM die Architektur benötigt.

Was Sie beim Self-Hosting von OpenBot-KI-Mitarbeitern erhalten

Sie hosten OpenBot-KI-Mitarbeiter selbst, indem Sie einen Gateway-Server sowie einen Container pro Bot auf von Ihnen kontrollierter Hardware betreiben. Jeder Bot-Container enthält einen eigenen Chromium-Browser und ein eigenes Workspace-Volume. Das Browserprofil bleibt zwischen Sitzungen erhalten. Jede Aktion eines Bots auf einem Computer, in einer Datei, auf einem MCP-Server (Model Context Protocol) oder in einer UI-Komponente läuft über dieses Gateway. Das Gateway prüft die Aktion vor ihrer Ausführung anhand einer Richtlinie und protokolliert sie anschließend.

OpenBot wird von CopilotKit unter der MIT-Lizenz auf github.com/CopilotKit/openbot veröffentlicht. Das erste getaggte Release, v0.0.1, wurde am 17. August 2026 veröffentlicht. Das Projekt bezeichnet sich selbst als Alpha-Version und befindet sich in aktiver Entwicklung. Betrachten Sie es als solide konzipierte Software mit noch vorhandenen Unreifeerscheinungen.

Der interessante Teil dieser Architektur ist zugleich der kostenintensive. Ein Browser pro Agent verursacht den Speicherbedarf, den viele bei der Planung übersehen. Deshalb steht hier die Dimensionierung vor der Installation.

Wie das Gateway jede Aktion entscheidet

Der API-Server auf Port 3001 ist der einzige Zugriffspfad zum Computer eines Bots. Bevor eine Browseraktion ausgeführt wird, ermittelt das Gateway das Ziel anhand eines Seiten-Snapshots, wertet CEL-Regeln (Common Expression Language) anhand des Kontexts aus, schreibt eine Audit-Zeile mit der Entscheidung und ruft erst danach den Container auf. Wenn die Ausführung anschließend fehlschlägt, schreibt es eine zweite Zeile. Die Dokumentation beschreibt diese Grenze eindeutig: Der Computer entscheidet nicht über Richtlinien. Das Server-Gateway bildet die Aktionsgrenze.

Richtlinien verwenden standardmäßig eine Verweigerungslogik, und Verweigerungsregeln werden vor Erlaubnisregeln ausgewertet. Die Richtung eines Fehlers ist wichtiger als die Syntax der Regel. Eine fehlende Richtlinie erlaubt nichts. Eine fehlerhafte Regel führt unabhängig davon zur Blockierung, ob es sich um eine Verweigerungs- oder Erlaubnisregel handelt. Ein Fehler in Ihrer Richtlinie führt daher zu einem blockierten Bot und nicht zu einem Bot, der unkontrolliert auf Ihre Konten zugreift.

Der Audit-Verlauf liegt in PostgreSQL und bleibt daher nach einem Neustart erhalten. Steuerungsübergaben werden als computer.help_requested, computer.control_taken und computer.control_released erfasst. So sehen Sie, wann ein Bot einen Menschen anfordert und wann der Mensch die Steuerung zurückgibt. Geheimnisse werden als Zeichenanzahl und niemals als Werte erfasst. Dateioperationen erfassen den Pfad und die Größe, niemals den Inhalt. Wenn Sie dieselbe Kontrollgrenze ohne einen dahinterliegenden Browser benötigen, behandelt KI-Agent-Aktionen durch Freigaben steuern diesen engeren Anwendungsfall.

Was ein einzelner Bot an RAM und Speicherplatz benötigt

Das Projekt veröffentlicht Messwerte für einen einzelnen Bot auf arm64. Das sind die einzigen Größenangaben, die OpenBot bereitstellt. Sie beschreiben einen Bot auf einer Architektur und sollten daher als Ausgangspunkt dienen, nicht als Kapazitätsplanung.

ChartOpenBot published resource figures, one Bot on arm64 (August 2026)
The data behind this chart
[
  {
    "label": "Measured, one Bot",
    "memory_gb": 0.55,
    "disk_gb": 5.3,
    "vcpu": 0.06
  },
  {
    "label": "Documented minimum",
    "memory_gb": 2,
    "disk_gb": 8,
    "vcpu": 1
  },
  {
    "label": "Documented recommended",
    "memory_gb": 4,
    "disk_gb": 10,
    "vcpu": 2
  }
]

Der maximale Speicherbedarf für einen Bot wurde mit 0.55 GB gemessen. Das dokumentierte Minimum beträgt 2 GB, die Empfehlung 4 GB. Der Abstand zwischen Messwert und Minimum lässt Chromium unter Last wachsen, weil der Speicherbedarf eines Browsers von den geöffneten Seiten abhängt und nicht vom Prozess im Leerlauf. Die CPU-Auslastung ist nahezu null. Am oberen Ende des Messbereichs beträgt sie 0.06 eines Cores. CPU ist daher nicht der begrenzende Faktor. Der Speicherplatz ist es. Das Image allein benötigt 5.3 GB. Empfohlen wird ein Volume mit 10 GB. Das Image ist so groß, weil es neben Chromium auch die Playwright-Binärdateien für Firefox und WebKit enthält.

Diese Angaben zeigen nicht, wie viel mehrere Bots zusammen benötigen. Das Projekt veröffentlicht dafür keinen Wert. Messen Sie den Bedarf selbst. Starten Sie einen Bot, geben Sie ihm eine realistische Aufgabe mit einer geöffneten Seite und überwachen Sie den Container während der Ausführung.

docker stats --no-stream
free -m

Verwenden Sie für den Container des Bots den Wert aus der Spalte MEM USAGE als Bedarf pro Bot. Addieren Sie Gateway und PostgreSQL und multiplizieren Sie den Bedarf pro Bot anschließend mit der Anzahl der Bots, die voraussichtlich gleichzeitig vorhanden sind. Auch ein unbeschäftigter Bot hält einen Browserprozess offen. Der Multiplikator gilt daher für vorhandene Bots, nicht nur für gerade aktive Bots. Die Berechnung entspricht derjenigen für die Dimensionierung von RAM und CPU für eine Coding-Agent-VPS. Die Browser-Komponente wird unter den Betrieb eines Headless-Browsers für Agents auf einer VPS behandelt.

Ein Detail von Chromium ist für kleine Pläne relevant. OpenBot startet Chromium mit --disable-dev-shm-usage. Dadurch schreibt der Browser nach /tmp statt nach /dev/shm. Das verhindert den Absturz auf Hosts mit einem kleinen /dev/shm. Gleichzeitig verlagert es die Belastung auf Ihr Root-Dateisystem. Das ist ein weiterer Grund dafür, dass der empfohlene Speicherplatz größer ist als das Image.

Wie hosten Sie OpenBot selbst auf einem VPS?

Sie benötigen Docker, Bun 1.3 oder neuer, ein CopilotKit-Intelligence-Projekt und einen API-Schlüssel für das Modell. Die Entwicklungsdokumentation setzt außerdem voraus, dass lsof, python3 und curl auf dem System vorhanden sind. Klonen Sie statt main ein getaggtes Release, weil sich main bei einem Alpha-Projekt ohne Vorwarnung ändert.

git clone --branch v0.0.1 https://github.com/CopilotKit/openbot.git
cd openbot
cp .env.example .env

Richten Sie das Intelligence-Projekt ein. Diese drei Befehle schreiben den Laufzeitschlüssel und das Lizenz-Token in Ihre Umgebungsdatei.

npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --write

Generieren Sie den Schlüssel, der gespeicherte Zugangsdaten verschlüsselt, und tragen Sie die Ausgabe als KEY_ENCRYPTION_KEY in .env ein. Fügen Sie OPENAI_API_KEY in derselben Datei hinzu oder setzen Sie BOT_PROVIDER auf anthropic oder google mit dem passenden Schlüssel.

openssl rand -base64 32

Installieren und starten Sie anschließend.

bun install
bash scripts/start.sh

scripts/start.sh startet die Docker-Dienste, führt die Datenbankmigrationen aus, startet den Server und die Anwendung und prüft deren Status. Nach Abschluss antwortet die Anwendung auf Port 3010 und die API auf Port 3001. Das Skript meldet Portkonflikte und lässt einen bereits laufenden passenden Dienst unverändert. Sie können es daher sicher zweimal ausführen.

Prüfen Sie die Installation zuerst direkt auf dem Server, bevor Sie etwas nach außen freigeben.

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3010
ss -ltnp | grep -E ':(3010|3001|4100|4500|5432)'

Ein 200 aus dem ersten Befehl bedeutet, dass die Anwendung Anfragen verarbeitet. Der zweite Befehl zeigt, an welche Adressen diese Ports gebunden sind. Das ist auf einem VPS die entscheidende Information. Eine Zeile mit 127.0.0.1:3001 ist auf das System selbst beschränkt. Eine Zeile mit 0.0.0.0:3001 bedeutet, dass jeder, der den Server über das Netzwerk erreichen kann, auch diese Ports erreichen kann.

Das einzelne Container-Image

Die Bereitstellungsdokumentation enthält außerdem ein einzelnes Image, das die Anwendung, die API und Chromium enthält und auf Port 3001 bereitgestellt wird.

docker build -t openbot .
docker run -p 127.0.0.1:3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql/data openbot

EMBEDDED_POSTGRES=on führt PostgreSQL innerhalb des Containers aus und wendet beim Start Migrationen an. Das benannte Volume bewahrt den Audit-Verlauf über eine erneute Bereitstellung hinweg. Ohne dieses Volume wird der Verlauf bei jedem Neuaufbau verworfen. Wenn Sie DATABASE_URL stattdessen auf eine verwaltete Datenbank verweisen, muss dort die Erweiterung vector aktiviert sein. Verwaltete Dienste wie RDS, Cloud SQL und Azure Database unterstützen die Erweiterung. Keiner dieser Dienste aktiviert sie jedoch für Sie. Eine Migration gegen eine frisch bereitgestellte verwaltete Datenbank schlägt daher fehl, weil der Spaltentyp vector noch nicht vorhanden ist.

Führen Sie Migrationen als Release-Schritt aus, wenn die Datenbank extern betrieben wird.

docker run --rm --env-file .env openbot \
  sh -c "cd /app/server && bun x drizzle-kit migrate --config=drizzle.config.ts"

Dieses Image veröffentlicht den Browser-Port absichtlich nicht. Es enthält außerdem keinen Supervisor, weil der Supervisor den Docker-Socket benötigt und serverless Plattformen diesen nicht bereitstellen. Ohne den Supervisor verwenden alle Bots denselben Browser und damit denselben Satz von Anmeldedaten. Dadurch entfällt die Isolation, die separate Container pro Bot sinnvoll macht. Wenn separate Anmeldedaten pro Bot der Grund für Ihren Einsatz sind, starten Sie den Compose-Stack mit gesetzten Variablen COMPUTER_SUPERVISOR_URL und SUPERVISOR_TOKEN auf einem Host, auf dem Sie diesen Kompromiss akzeptieren. Ein Prozess, der mit dem Docker-Socket kommunizieren kann, kann einen privilegierten Container starten. In der Praxis hat er damit root-Rechte auf dem Host. Das ist ein guter Grund, OpenBot auf einem eigenen Rechner zu betreiben, entsprechend dem Ansatz Coding-Agenten eine kurzlebige VM bereitzustellen.

Warum OPENBOT_SINGLE_USER eine Laptop-Einstellung ist

.env.example wird mit OPENBOT_SINGLE_USER=true ausgeliefert. Diese Einstellung behandelt jede Anfrage als Anmeldung eines einzelnen Administrators und überspringt die Anmeldung vollständig. Auf einem Laptop ist das praktisch, weil nur Sie den Port erreichen können. Auf einem VPS bedeutet es, dass die erste Person, die Port 3010 erreicht, Administrator eines Systems wird, das verschlüsselte Zugangsdaten speichert und einen Browser steuert, in dem Sie bereits bei Ihren Konten angemeldet sind.

Es gibt zwei sichere Möglichkeiten, die Anwendung zu betreiben. Behalten Sie OPENBOT_SINGLE_USER=true bei, binden Sie jeden Port an 127.0.0.1 und greifen Sie nur über einen SSH-Tunnel oder eine private Netzwerkschnittstelle auf die Anwendung zu.

ssh -N -L 3010:127.0.0.1:3010 -L 3001:127.0.0.1:3001 you@your-vps

Die Anwendung ist dann unter http://localhost:3010 in Ihrem eigenen Browser erreichbar. Das gilt als sicherer Kontext. Daher funktionieren sowohl Anmeldecookies als auch die Browserfunktionen, die die Live-Anzeige benötigt. Die andere Möglichkeit besteht darin, den Einzelbenutzermodus zu deaktivieren und einen echten Identitätsanbieter zu konfigurieren. Google, Microsoft Entra, Okta, SAML und OIDC werden unterstützt. Jeder Anbieter benötigt außerdem BETTER_AUTH_SECRET mit mindestens 32 Zeichen, BETTER_AUTH_URL mit der öffentlichen API-Basis-URL für OAuth-Rückrufe, INITIAL_ADMIN_EMAILS und TRUSTED_ORIGINS. Die Zugangsdaten des Anbieters müssen vollständig sein. Ein nur teilweise konfigurierter Anbieter verhindert den Start, statt auf offenen Zugriff zurückzufallen.

Wenn die Anwendung unter einem öffentlichen Namen erreichbar ist, schalten Sie TLS (Transport Layer Security) davor. Eine Seite, die über schlichtes http:// und nicht über localhost ausgeliefert wird, gilt nicht als sicherer Kontext. Daher werden Cookies mit dem Attribut Secure nicht gespeichert, und die Anmeldung schlägt auf eine Weise fehl, die wie ein Fehler in OpenBot aussieht.

Firewall für niedrigere Ports

In OpenBots eigenem Sicherheitshinweis steht, dass die Endpunkte der niedrigeren Dienste durch Token geschützt sind, privat bleiben sollen und nicht zum Umgehen des Gateways verwendet werden dürfen. Token sind die zweite Schutzmaßnahme. Die erste besteht darin, dass der Port überhaupt nicht erreichbar ist.

Der Agent-Computer lauscht auf Port 4100 und erfordert COMPUTER_TOKEN. Die Bot-Endpunkte lauschen auf den Ports 4200 und 4201. Der Supervisor lauscht auf dem Host auf Port 4500 und innerhalb seines Containers auf Port 4300. PostgreSQL lauscht auf Port 5432. Keiner dieser Ports gehört auf eine öffentliche Schnittstelle. Bei einer Bereitstellung für einen einzelnen Benutzer gilt das auch für die Anwendung und die API.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

Hier gibt es eine Falle für alle, die annehmen, dass die Firewall ausreicht. Wenn Sie einen Container-Port mit -p 3001:3001 veröffentlichen, installiert Docker eine DNAT-Regel. Dadurch wird der Datenverkehr im FORWARD-Pfad verarbeitet und durchläuft nie die INPUT-Kette, für die ufws standardmäßige Ablehnung gilt. Der Port bleibt geöffnet, obwohl ufw status weiterhin Status: active ausgibt. Binden Sie den veröffentlichten Port direkt in der Zuordnung an Loopback, etwa mit -p 127.0.0.1:3001:3001, oder setzen Sie die Hostadresse in Ihrer Compose-Datei. Prüfen Sie dies mit ss -ltnp und nicht mit ufw status.

OpenBot ist kein vollständig lokaler Stack

Klären Sie das, bevor Sie die Bereitstellung planen. OpenBot hängt von einem CopilotKit-Intelligence-Projekt ab. Dieses speichert dauerhafte Threads und den Gesprächskontext außerhalb Ihres Systems. Der Server prüft INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL, INTELLIGENCE_API_KEY und COPILOTKIT_LICENSE_TOKEN beim Start. Alle vier müssen gemeinsam vorhanden sein. Andernfalls schlägt der Start fehl. Seit August 2026 ist ein kostenloser Tarif verfügbar. Intelligence lässt sich außerdem selbst hosten. Eine vollständig lokale Bereitstellung ist daher möglich, erfordert aber mehr Arbeit als im Quickstart beschrieben.

Das Modell ist die zweite externe Abhängigkeit. Im Paket ist kein Modell enthalten. BOT_PROVIDER akzeptiert openai, anthropic oder google. OPENAI_BASE_URL richtet den OpenAI-Pfad auf einen beliebigen kompatiblen Endpunkt. Hier passt Ollama auf einem VPS ausführen, um ein LLM selbst zu hosten, wenn die Tokens auf Ihrer eigenen Hardware bleiben sollen. Die Browsersteuerung stellt hohe Anforderungen an ein Modell. Testen Sie daher ein lokales Modell mit einer realen Aufgabe, bevor Sie sich dafür entscheiden.

Führen Sie vorerst eine einzige Replica aus

Das Gateway cached Seiten-Snapshots im Arbeitsspeicher des Serverprozesses. Bei zwei Replicas ist ein von einem Prozess erstellter Snapshot für den anderen Prozess nicht sichtbar. Dadurch schlagen Aktionen sporadisch mit element-not-found-Fehlern fehl, die zufällig wirken. Die Bereitstellungsdokumentation ist eindeutig: Führen Sie eine einzige Replica aus und setzen Sie die maximale Instanzanzahl Ihrer Plattform auf 1. Diese Begrenzung entfällt, sobald das Caching der Snapshots in die Datenbank verlagert wird. Bis dahin skalieren Sie OpenBot, indem Sie den Server leistungsfähiger machen, nicht indem Sie weitere Server hinzufügen. Die Isolation zwischen den Bots wird weiterhin durch die Container pro Bot gewährleistet. Das funktioniert genauso wie bei selbst gehosteten Agent-Sandboxes, die verhindern, dass sich die Fehler eines Agents auf andere auswirken.

Fehlerfälle und ihre sichtbaren Auswirkungen

Der Startvorgang wird unmittelbar nach dem Ausfüllen von .env beendet. Der Server prüft die Konfiguration, bevor er Anfragen verarbeitet. Ein unvollständiger Intelligence-Block, ein fehlendes KEY_ENCRYPTION_KEY oder ein OAuth-Provider mit Client-ID, aber ohne Secret beendet den Startvorgang, statt stillschweigend mit Einschränkungen weiterzulaufen. Lesen Sie den ersten Fehler, korrigieren Sie dieses eine Feld und starten Sie den Server erneut.

Migrationen schlagen bei einer verwalteten Datenbank fehl. Die Erweiterung vector ist standardmäßig nicht aktiviert. Deshalb trifft die Migration auf einen Spaltentyp, den PostgreSQL nicht kennt. Verbinden Sie sich als Superuser, führen Sie CREATE EXTENSION vector; aus und wiederholen Sie anschließend den Migrationsschritt.

Die Anwendung wird geladen, aber die Anmeldung bleibt nicht bestehen. Sie stellen die Anwendung über unverschlüsseltes http:// unter einer öffentlichen Adresse bereit. Das ist kein sicherer Kontext, daher verwirft der Browser das Secure-Cookie. Schalten Sie TLS davor oder verwenden Sie den SSH-Tunnel, damit der Browser localhost erkennt.

Bots verwenden dieselben Anmeldedaten, obwohl Sie getrennte Sitzungen erwartet haben. Der Supervisor läuft nicht. Daher gibt es keinen Computer pro Bot, und alle Bots verwenden den gemeinsamen Browser. Prüfen Sie, ob COMPUTER_SUPERVISOR_URL gesetzt ist und der Supervisor den Docker-Socket erreichen kann.

Ein Bot hält an und fordert Hilfe an. Das entspricht dem vorgesehenen Verhalten. Der Audit-Trail protokolliert computer.help_requested. Sie übernehmen die Kontrolle auf dem Live-Bildschirm, und die Übergabe wird auf beiden Seiten protokolliert.

FAQ

Ist es sicher, OPENBOT_SINGLE_USER bei einer VPS-Bereitstellung aktiviert zu lassen?

Nur wenn das Gateway nicht aus dem Internet erreichbar ist. OPENBOT_SINGLE_USER=true akzeptiert jede Anfrage als ein Administrator ohne Anmeldung. Jeder, der den Port öffnen kann, hat damit vollständige Kontrolle über die Bereitstellung, die gespeicherten Zugangsdaten und den angemeldeten Browser. Das ist vertretbar, wenn jeder Port an 127.0.0.1 gebunden ist und Sie über einen SSH-Tunnel oder eine private Netzwerkschnittstelle auf die Anwendung zugreifen. Über eine öffentliche Schnittstelle müssen Sie die Option deaktivieren und Google, Microsoft Entra, Okta oder OIDC zusammen mit BETTER_AUTH_SECRET, BETTER_AUTH_URL, INITIAL_ADMIN_EMAILS und TRUSTED_ORIGINS konfigurieren.

Wie viel RAM benötigt ein OpenBot-Bot?

Die veröffentlichten Angaben des Projekts für einen einzelnen Bot auf arm64 nennen einen Spitzenverbrauch von 0.55 GB. Als dokumentiertes Minimum gelten 2 GB, empfohlen werden 4 GB. Für mehrere gleichzeitig ausgeführte Bots gibt es keine veröffentlichten Angaben, weil jeder Bot eine eigene Chromium-Instanz verwendet. Führen Sie einen Bot mit einer realen Aufgabe aus, lesen Sie den Speicherverbrauch dieses Containers in docker stats ab, addieren Sie Gateway und Datenbank und multiplizieren Sie den Wert mit der erwarteten Anzahl gleichzeitig laufender Bots.

Benötige ich ein CopilotKit-Konto, um OpenBot selbst zu hosten?

Ja. OpenBot benötigt ein CopilotKit-Intelligence-Projekt für dauerhafte Threads und den Speicher. Der Server startet nicht, wenn die Intelligence API URL, die Gateway WebSocket URL, der API key oder das license token fehlt. Seit August 2026 ist ein kostenloser Tarif verfügbar. Intelligence kann außerdem selbst gehostet werden, sodass sich die gehostete Abhängigkeit mit zusätzlichem Aufwand entfernen lässt. Sie müssen auch Ihren eigenen model API key angeben, da OpenBot kein Modell mitliefert.

Warum erhält jeder Bot einen eigenen Browser, statt einen gemeinsamen zu verwenden?

Weil ein Browserprofil eine Identität darstellt. Ein gemeinsam verwendeter Browser bedeutet gemeinsame Cookies und gemeinsame Sitzungen. Ist ein Bot bei einem Konto angemeldet, sind es dadurch alle Bots. Container pro Bot geben jedem Mitarbeiter ein eigenes Profil und eigene Anmeldungen. Der Nachteil ist der höhere Speicherbedarf, da eine Chromium-Instanz pro Bot den größten einzelnen Posten bei der Dimensionierung darstellt.

Welche OpenBot-Ports sollten in der Firewall geöffnet werden?

Keine der internen Ports. Der Agent-Computer auf 4100, die Bot-Endpunkte auf 4200 und 4201, der Supervisor auf 4500 und PostgreSQL auf 5432 bleiben privat. Das Projekt schützt sie mit Tokens und verlangt, dass sie trotzdem nicht erreichbar sind. Veröffentlichen Sie nur die Ports, die eine Person zum Öffnen benötigt. Beachten Sie außerdem, dass ein mit -p 3001:3001 veröffentlichter Container-Port unabhängig von einer ufw default-deny-Regel erreichbar ist, weil die DNAT-Regel von Docker diesen Datenverkehr in den FORWARD-Pfad statt in INPUT einordnet.