OpenBot AI-collega's zelf hosten op een VPS
Leer hoe u OpenBot AI-collega's zelf host met aparte containers en browsers. Ontdek hoe de gateway acties valideert en bereken het RAM-geheugen dat u per bot nodig heeft.
Wat u krijgt bij het zelf hosten van OpenBot AI-collega's
U host OpenBot AI-collega's zelf door één gateway-server en één container per bot uit te voeren op hardware die u beheert. Elke bot-container bevat een eigen Chromium-browser en een eigen werkruimte-volume, met een browserprofiel dat tussen sessies behouden blijft. Elke actie die een bot uitvoert op een computer, een bestand, een MCP (model context protocol)-server of een UI-component verloopt via die gateway. De gateway toetst de actie aan een beleid voordat deze plaatsvindt en legt deze achteraf vast.
OpenBot wordt uitgebracht door CopilotKit onder de MIT-licentie op github.com/CopilotKit/openbot. De eerste getagde release, v0.0.1, werd gepubliceerd op 17 augustus 2026. Het project omschrijft zichzelf als alpha en is in actieve ontwikkeling. Beschouw het als een serieus ontwerp met nog enkele kinderziektes.
Het interessante deel van die architectuur is tevens het kostbare deel. Een browser voor elke agent is de geheugenkostenpost waar de meeste mensen geen rekening mee houden bij de planning. Daarom is het bepalen van de benodigde capaciteit hier de eerste stap vóór de installatie.
Hoe de gateway elke actie bepaalt
De API-server op poort 3001 is het enige toegangspunt tot de computer van een bot. Voordat een browseractie wordt uitgevoerd, bepaalt de gateway het doel op basis van een paginasnapshot, evalueert deze CEL (common expression language) beleidsregels op basis van de context, schrijft een audit-regel met de beslissing en roept pas daarna de container aan. Als de uitvoering daarna mislukt, schrijft de gateway een tweede regel. De documentatie stelt de grens duidelijk vast: de computer bepaalt het beleid niet; de server-gateway vormt de grens voor acties.
Het beleid is standaard 'deny-by-default' en 'deny'-regels worden geëvalueerd vóór 'allow'-regels. De richting van de fout is belangrijker dan de syntaxis van de regel. Een ontbrekend beleid staat niets toe en een defecte regel leidt tot blokkering, ongeacht of het een 'deny'- of 'allow'-regel betreft. Een fout in uw beleid resulteert dus in een geblokkeerde bot in plaats van een bot die ongecontroleerd toegang heeft tot uw accounts.
Het audit-spoor bevindt zich in PostgreSQL, waardoor het een herstart overleeft. Overdrachten van controle worden vastgelegd als computer.help_requested, computer.control_taken en computer.control_released; op deze manier ziet u hoe een bot om een mens vraagt en hoe de mens de controle weer overdraagt. Geheimen worden geregistreerd als aantal tekens, nooit als waarden. Bij bestandsbewerkingen worden het pad en de grootte vastgelegd, nooit de inhoud. Als u dezelfde controlegrens wilt zonder browser erachter, behandelt het beveiligen van AI-agentacties met goedkeuringen dat specifiekere scenario.
Wat één bot kost aan RAM en schijfruimte
Het project publiceert gemeten cijfers voor één enkele Bot op arm64. Dit zijn de enige dimensioneringscijfers die OpenBot vrijgeeft. Ze beschrijven één bot op één architectuur; beschouw ze daarom als uitgangspunt en niet als een capaciteitsplan.
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
}
]Het piekgeheugengebruik werd gemeten op 0.55 GB voor één Bot, terwijl het gedocumenteerde minimum 2 GB is en de aanbeveling 4 GB bedraagt. Het verschil tussen de meting en het minimum is de ruimte die Chromium nodig heeft om onder belasting te groeien, aangezien het geheugengebruik van een browser afhangt van de geopende pagina's en niet van het proces in ruststand. Het CPU-gebruik in ruststand is verwaarloosbaar, op 0.06 van een core aan de bovengrens van het gemeten bereik; u schaft dus geen CPU-capaciteit aan. Schijfruimte is de bepalende factor. De image alleen al is 5.3 GB, tegenover een aanbevolen volume van 10 GB. Deze omvang is nodig omdat de image naast Chromium ook de Firefox- en WebKit-binaries van Playwright bevat.
Niets hiervan vertelt u wat meerdere bots samen kosten, en het project publiceert hier geen cijfers over. Meet dit zelf. Start één bot, geef deze een echte taak met een geopende pagina en monitor de container terwijl deze werkt.
docker stats --no-stream
free -mGebruik de MEM USAGE-kolom voor de container van de bot als uw cijfer per bot, tel daar de gateway en PostgreSQL bij op en vermenigvuldig het cijfer per bot met het aantal bots dat u gelijktijdig verwacht te draaien. Een inactieve bot houdt nog steeds een browserproces vast, dus de vermenigvuldiger is van toepassing op alle bestaande bots, niet alleen op de actieve. De berekening is dezelfde als die voor het dimensioneren van RAM en CPU voor een VPS voor coding agents, en het browser-aspect hiervan wordt behandeld in het draaien van een headless browser voor agents op een VPS.
Eén detail over Chromium is van invloed op kleine abonnementen. OpenBot start Chromium met --disable-dev-shm-usage, waardoor de browser naar /tmp schrijft in plaats van naar /dev/shm. Dit voorkomt de crash die optreedt op hosts met een kleine /dev/shm en verplaatst de druk naar uw root-bestandssysteem. Dit is een extra reden waarom de aanbevolen schijfruimte groter is dan de image zelf.
Hoe host u OpenBot zelf op een VPS?
U heeft Docker, Bun 1.3 of nieuwer, een CopilotKit Intelligence-project en een model-API-key nodig. De ontwikkelingsdocumentatie vereist ook lsof, python3 en curl op de server. Kloon een getagde release in plaats van main, omdat main bij een alfaproject zonder waarschuwing wijzigt.
git clone --branch v0.0.1 https://github.com/CopilotKit/openbot.git
cd openbot
cp .env.example .envProvisioneer het Intelligence-project. Deze drie commando's schrijven de runtime-key en het licentietoken naar uw omgevingsbestand.
npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --writeGenereer de sleutel die opgeslagen inloggegevens versleutelt en plaats de uitvoer in .env als KEY_ENCRYPTION_KEY. Voeg uw OPENAI_API_KEY toe in hetzelfde bestand, of stel BOT_PROVIDER in op anthropic of google met de bijbehorende sleutel.
openssl rand -base64 32Installeer en start vervolgens de applicatie.
bun install
bash scripts/start.shscripts/start.sh start de Docker-services, voert de databasemigraties uit, start de server en de app, en controleert hun status. Wanneer dit proces is voltooid, reageert de app op poort 3010 en de API op poort 3001. Het script rapporteert poortconflicten en laat een reeds draaiende, overeenkomstige service ongemoeid; het script twee keer uitvoeren is dus veilig.
Controleer de werking vanaf de server zelf voordat u services blootstelt aan het internet.
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3010
ss -ltnp | grep -E ':(3010|3001|4100|4500|5432)'Een 200 bij het eerste commando betekent dat de app actief is. Het tweede commando toont aan welke adressen deze poorten zijn gebonden, en dat is het antwoord dat ertoe doet op een VPS. Een regel met 127.0.0.1:3001 is privé voor de server. Een regel met 0.0.0.0:3001 betekent dat iedereen die een route naar de server heeft, de service kan bereiken.
De container-image voor alles-in-één
De documentatie voor de implementatie levert ook een enkele image die de applicatie, de API en Chromium bevat, welke wordt aangeboden op poort 3001.
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 openbotEMBEDDED_POSTGRES=on draait PostgreSQL binnen de container en voert migraties uit bij het opstarten. Het benoemde volume behoudt de audit-geschiedenis bij een herimplementatie; zonder dit volume gaat die geschiedenis bij elke herbouw verloren. Als u DATABASE_URL naar een beheerde database verwijst, moet de vector-extensie daarop zijn ingeschakeld. Beheerde diensten zoals RDS, Cloud SQL en Azure Database ondersteunen deze extensie, maar geen van deze diensten schakelt deze automatisch voor u in. Hierdoor mislukt een migratie op een nieuwe beheerde database omdat het kolomtype vector nog niet bestaat.
Voer migraties uit als een release-stap wanneer de database extern is.
docker run --rm --env-file .env openbot \
sh -c "cd /app/server && bun x drizzle-kit migrate --config=drizzle.config.ts"Die image laat de browserpoort bewust ongepubliceerd. Ook de supervisor is weggelaten, omdat de supervisor toegang nodig heeft tot de Docker-socket, wat serverless-platforms niet bieden. Zonder de supervisor deelt elke bot één browser en daarmee één set inloggegevens. Dit heft de isolatie op die het draaien van aparte containers per bot juist waardevol maakte. Als u hier bent vanwege de behoefte aan aparte inloggegevens per bot, draai dan de compose-stack met COMPUTER_SUPERVISOR_URL en SUPERVISOR_TOKEN ingesteld, op een host waar u de afweging accepteert. Een proces dat kan communiceren met de Docker-socket kan een geprivilegieerde container starten; in de praktijk is dit dus root op de host. Dat is een goede reden om OpenBot op een eigen machine te draaien, in dezelfde geest als het geven van een wegwerp-VM aan programmeer-agents.
Waarom OPENBOT_SINGLE_USER een instelling voor laptops is
.env.example wordt geleverd met OPENBOT_SINGLE_USER=true. Deze instelling accepteert elk verzoek als één beheerder en slaat het inloggen volledig over. Op een laptop is dit handig, omdat u de enige client bent die de poort kan bereiken. Op een VPS betekent dit dat de eerste persoon die poort 3010 bereikt, beheerder wordt van een systeem dat versleutelde inloggegevens opslaat en een browser aanstuurt die al is ingelogd op uw accounts.
Er zijn twee correcte manieren om dit te draaien. Behoud OPENBOT_SINGLE_USER=true, bind elke poort aan 127.0.0.1 en benader de applicatie uitsluitend via een SSH-tunnel of een privé-netwerkinterface.
ssh -N -L 3010:127.0.0.1:3010 -L 3001:127.0.0.1:3001 you@your-vpsDe applicatie is dan beschikbaar op http://localhost:3010 in uw eigen browser, wat geldt als een veilige context. Hierdoor werken inlogcookies en de browserfuncties die het live-scherm nodig heeft naar behoren. De andere manier is om de single-user modus uit te schakelen en een echte identiteitsprovider te configureren. Google, Microsoft Entra, Okta, SAML en OIDC worden ondersteund. Elke provider vereist ook BETTER_AUTH_SECRET van 32 tekens of meer, BETTER_AUTH_URL ingesteld op de publieke API-basis-URL voor OAuth-callbacks, INITIAL_ADMIN_EMAILS en TRUSTED_ORIGINS. Provider-inloggegevens moeten volledig zijn, omdat een half geconfigureerde provider het opstarten stopt in plaats van terug te vallen op open toegang.
Als de applicatie bereikbaar is via een publieke naam, plaats er dan TLS (transport layer security) voor. Een pagina die wordt geserveerd via onversleuteld http:// op iets anders dan localhost is geen veilige context. Hierdoor worden cookies met de markering Secure niet opgeslagen en mislukt het inloggen op een manier die lijkt op een bug in OpenBot.
Beveilig de poorten op laag niveau
De eigen beveiligingsnotitie van OpenBot stelt dat de service-endpoints op laag niveau worden beschermd door tokens, dat u deze privé moet houden en dat u ze niet moet gebruiken om de gateway te omzeilen. Tokens vormen de tweede beveiligingslaag. De eerste laag is dat de poort in het geheel niet bereikbaar is.
De agent-computer luistert op 4100 en vereist COMPUTER_TOKEN. De bot-endpoints luisteren op 4200 en 4201. De supervisor luistert op 4500 op de host en op 4300 binnen de container. PostgreSQL luistert op 5432. Geen van deze hoort op een publieke interface thuis, en bij een implementatie voor één gebruiker geldt dit ook voor de app en de API.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verboseEr is hier een valkuil voor mensen die aannemen dat de firewall voldoende is. Het publiceren van een containerpoort met -p 3001:3001 zorgt ervoor dat Docker een DNAT-regel installeert. Hierdoor wordt verkeer afgehandeld in het FORWARD-pad en passeert het nooit de INPUT-chain die door het standaard 'deny'-beleid van ufw wordt beheerd. De poort blijft open terwijl ufw status nog steeds Status: active weergeeft. Koppel de gepubliceerde poort aan de loopback-interface in de mapping zelf, zoals -p 127.0.0.1:3001:3001, of stel het hostadres in uw compose-bestand in. Controleer dit met ss -ltnp, niet met ufw status.
OpenBot is geen offline stack
Houd hier rekening mee voordat u de implementatie plant. OpenBot is afhankelijk van een CopilotKit Intelligence-project, dat duurzame threads en gespreksgeheugen buiten uw eigen server opslaat. De server valideert INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL, INTELLIGENCE_API_KEY en COPILOTKIT_LICENSE_TOKEN bij het opstarten; alle vier moeten aanwezig zijn, anders mislukt het opstarten. Sinds augustus 2026 is er een gratis abonnement beschikbaar en Intelligence is zelf te hosten, waardoor een volledig lokale implementatie mogelijk is, al vereist dit meer werk dan de quickstart laat zien.
Het model is de tweede externe afhankelijkheid. Niets wordt standaard meegeleverd. BOT_PROVIDER accepteert openai, anthropic of google, en OPENAI_BASE_URL wijst het OpenAI-pad naar elk compatibel eindpunt. Hier past Ollama draaien op een VPS om zelf een LLM te hosten als u wilt dat de tokens op uw eigen hardware blijven. Browserbesturing vraagt veel van een model, dus test een lokaal model met een echte taak voordat u besluit dit te gebruiken.
Draai voorlopig één replica
De gateway slaat pagina-snapshots op in het geheugen van het serverproces. Bij twee replica's is een snapshot van het ene proces onzichtbaar voor het andere, waardoor acties met tussenpozen falen met element-not-found-fouten die willekeurig lijken. De documentatie voor de implementatie is expliciet: draai een enkele replica en beperk het maximale aantal instanties van uw platform tot 1. Die limiet vervalt zodra het opslaan van snapshots naar de database wordt verplaatst. Tot die tijd schaalt u OpenBot door de server krachtiger te maken, niet door meer servers toe te voegen. Isolatie tussen bots wordt nog steeds gewaarborgd door de containers per bot, op dezelfde manier waarop self-hosted agent sandboxes de fouten van de ene agent gescheiden houden van de andere.
Foutmodi en wat u zult zien
De opstartprocedure stopt onmiddellijk nadat u .env heeft ingevuld. De server valideert de configuratie voordat deze services aanbiedt. Een onvolledig Intelligence-blok, een ontbrekende KEY_ENCRYPTION_KEY of een OAuth-provider met een client ID maar zonder secret zorgen ervoor dat het opstarten stopt in plaats van dat de applicatie in een beperkte modus verdergaat. Lees de eerste foutmelding, corrigeer dat specifieke veld en start opnieuw.
Migraties mislukken op een beheerde database. De vector-extensie is standaard niet ingeschakeld, waardoor de migratie een kolomtype tegenkomt dat PostgreSQL niet herkent. Maak verbinding als superuser, voer CREATE EXTENSION vector; uit en voer daarna de migratiestap opnieuw uit.
De app laadt, maar inloggen blijft niet behouden. U gebruikt een onbeveiligde http://-verbinding op een publiek adres; dit is geen veilige context, waardoor de Secure-cookie wordt geweigerd. Plaats TLS voor de applicatie of gebruik de SSH-tunnel zodat de browser localhost detecteert.
Bots delen inloggegevens waarvan u verwachtte dat ze gescheiden zouden zijn. De supervisor draait niet, waardoor er geen computer per bot beschikbaar is en elke bot dezelfde browser gebruikt. Controleer of COMPUTER_SUPERVISOR_URL is ingesteld en of de supervisor de Docker-socket kan bereiken.
Een bot stopt en vraagt om hulp. Dit is het beoogde gedrag. Het audit-logboek legt computer.help_requested vast, u neemt de controle over op het live-scherm en de overdracht wordt aan beide kanten geregistreerd.
FAQ
Is het veilig om OPENBOT_SINGLE_USER ingeschakeld te laten voor een VPS-implementatie?
Alleen wanneer de gateway niet bereikbaar is vanaf het internet. OPENBOT_SINGLE_USER=true accepteert elk verzoek als één beheerder zonder inlogprocedure; iedereen die de poort kan openen, krijgt dus volledige controle over de implementatie, de opgeslagen inloggegevens en de ingelogde browser. Dit is acceptabel wanneer elke poort is gebonden aan 127.0.0.1 en u de applicatie benadert via een SSH-tunnel of een privé-netwerkinterface. Schakel dit op een publieke interface uit en configureer Google, Microsoft Entra, Okta of OIDC in combinatie met BETTER_AUTH_SECRET, BETTER_AUTH_URL, INITIAL_ADMIN_EMAILS en TRUSTED_ORIGINS.
Hoeveel RAM heeft één OpenBot-bot nodig?
De gepubliceerde cijfers van het project voor een enkele bot op arm64 stellen het piekgeheugengebruik vast op 0.55 GB, met 2 GB als het gedocumenteerde minimum en 4 GB als aanbevolen waarde. Er is geen gepubliceerd cijfer voor meerdere bots tegelijk, omdat elke bot een eigen Chromium-instantie draait. Laat één bot een echte taak uitvoeren, lees het geheugengebruik van die container uit in docker stats, tel de gateway en de database erbij op en vermenigvuldig dit met het aantal bots dat u gelijktijdig wilt draaien.
Heb ik een CopilotKit-account nodig om OpenBot zelf te hosten?
Ja. OpenBot is afhankelijk van een CopilotKit Intelligence-project voor duurzame threads en geheugen. De server weigert te starten tenzij de Intelligence API URL, de gateway WebSocket URL, de API-sleutel en het licentietoken zijn ingesteld. Sinds augustus 2026 is er een gratis abonnement beschikbaar en Intelligence kan zelf worden gehost, waardoor de afhankelijkheid van de gehoste dienst met extra inspanning kan worden verwijderd. U levert ook uw eigen model-API-sleutel aan, aangezien er geen model wordt meegeleverd met OpenBot.
Waarom krijgt elke bot een eigen browser in plaats van er een te delen?
Omdat een browserprofiel een identiteit is. Een gedeelde browser betekent gedeelde cookies en gedeelde sessies; één bot die is ingelogd op een account betekent dus dat alle bots op dat account zijn ingelogd. Containers per bot geven elke medewerker een eigen profiel en eigen inloggegevens. De kosten hiervan zijn geheugengebruik, aangezien een Chromium-instantie per bot de grootste factor is in de dimensionering.
Welke OpenBot-poorten moeten openstaan op de firewall?
Geen van de lagere poorten. De agent-computer op 4100, de bot-endpoints op 4200 en 4201, de supervisor op 4500 en PostgreSQL op 5432 moeten allemaal privé blijven. Het project beveiligt deze met tokens en verzoekt u ze hoe dan ook onbereikbaar te houden. Publiceer alleen wat een gebruiker nodig heeft om te openen, en onthoud dat een containerpoort die met -p 3001:3001 wordt gepubliceerd, bereikbaar is ongeacht een ufw default-deny regel. Dit komt doordat de DNAT-regel van Docker dat verkeer in het FORWARD-pad plaatst in plaats van INPUT.