Como hospedar colaboradores de IA OpenBot em um VPS
Veja como hospedar o OpenBot com um container, navegador Chromium e workspace por bot, como o gateway valida ações e quanta RAM essa arquitetura exige.
O que obtém ao alojar os seus colaboradores de IA OpenBot
Aloja os colaboradores de IA OpenBot ao executar um servidor gateway e um contentor por bot num hardware que controla. Cada contentor de bot inclui o seu próprio navegador Chromium e o seu próprio volume de workspace, com um perfil de navegador que persiste entre sessões. Todas as ações que um bot executa num computador, num ficheiro, num servidor MCP (model context protocol) ou num componente de UI passam por esse gateway. O gateway valida cada ação com base numa política antes de a executar e regista-a depois. Se o ciclo do agente encapsulado pelo gateway ainda não lhe for familiar, o percurso faseado em aprender agentes de IA do zero leva-o a criar primeiro um agente simples antes de dar a um bot acesso a um navegador e às suas credenciais de acesso.
O OpenBot é publicado pela CopilotKit sob a licença MIT em github.com/CopilotKit/openbot. A primeira versão etiquetada, v0.0.1, foi publicada em 17 August 2026, e o projeto descreve-se como alpha e em desenvolvimento ativo. Trate-o como um projeto sério, mas ainda com limitações próprias de uma fase inicial.
A parte interessante desta arquitetura também é a mais dispendiosa. Um navegador por agente é o custo de memória que a maioria das pessoas não planeia, por isso o dimensionamento vem antes da instalação.
Como o gateway decide cada ação
O servidor de API na porta 3001 é o único caminho para o computador de um bot. Antes de executar uma ação no navegador, o gateway resolve o alvo a partir de um snapshot da página, avalia as regras de política CEL (common expression language) em relação ao contexto, grava uma linha de auditoria com a decisão e só depois chama o container. Se a execução falhar depois disso, grava uma segunda linha. A documentação declara claramente este limite: o computador não decide a política; o gateway do servidor é o limite de execução das ações. Essa separação tem um nome fora do OpenBot, porque o ciclo, as definições das ferramentas, as verificações de permissões e o estado da sessão formam em conjunto o harness envolvido em torno de um modelo, e este gateway é a parte de permissões desse conjunto.
A política segue o princípio de negar por padrão, e as regras de negação são avaliadas antes das regras de permissão. A direção da falha é mais importante do que a sintaxe da regra. Uma política ausente não permite nada, e uma regra inválida falha no sentido do bloqueio, seja uma regra de negação ou de permissão. Portanto, um erro na política deixa o bot bloqueado, em vez de deixar o bot solto nas suas contas. Essa camada controla o que um bot faz, não o que lê. Por isso, uma página que contenha instruções dirigidas ao agente continua a ser um problema separado. É a mesma superfície de prompt injection que surge quando entrega a um agente resultados da sua própria instância do SearXNG.
O registo de auditoria fica no PostgreSQL, por isso sobrevive a um reinício. As transferências de controlo são registadas como computer.help_requested, computer.control_taken e computer.control_released. Assim, é possível ver quando um bot pede intervenção humana e quando a pessoa devolve o controlo ao bot. Os segredos são registados como contagens de caracteres, nunca como valores. As operações de ficheiros registam o caminho e o tamanho, nunca o conteúdo. Se quiser o mesmo limite de controlo sem um navegador por trás, a submissão das ações de agentes de IA a aprovações aborda esse caso mais restrito.
O consumo de RAM e disco de um bot
O projeto publica valores medidos para um único Bot em arm64. Estes são os únicos números de dimensionamento que o OpenBot fornece. Eles descrevem um bot numa arquitetura. Por isso, use-os como ponto de partida e não como um plano de capacidade.
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
}
]O pico de memória medido foi de 0.55 GB para um Bot. O mínimo documentado é 2 GB. A recomendação é 4 GB. A diferença entre o valor medido e o mínimo deixa margem para o Chromium aumentar o consumo sob carga. O consumo de memória de um browser depende das páginas abertas. Não depende apenas do processo em repouso. O consumo de CPU em idle é praticamente nulo. No extremo superior do intervalo medido, é de 0.06 de um core. Portanto, o principal recurso a dimensionar não é a CPU. É o disco. Só a imagem ocupa 5.3 GB. O volume recomendado tem 10 GB. A imagem é tão grande porque inclui os binários do Firefox e do WebKit do Playwright, além do Chromium.
Nada disso indica quanto vários bots consomem em conjunto. O projeto não publica esse valor. Um mínimo documentado é um valor que o projeto considera aceitável publicar. Não é necessariamente um valor observado sob carga. Por isso, a escolha entre PhotoPrism e Immich deve basear-se nos consumos mínimos de RAM medidos, e não nos valores publicados. Faça as suas próprias medições. Inicie um bot. Atribua-lhe uma tarefa real com uma página aberta. Monitorize o contentor enquanto a tarefa é executada.
docker stats --no-stream
free -mUse a coluna MEM USAGE do contentor do bot como valor por bot. Adicione o gateway e o PostgreSQL. Depois, multiplique o valor por bot pelo número de bots que espera ter em execução ao mesmo tempo. Um bot em idle mantém um processo do browser. Por isso, o multiplicador aplica-se aos bots existentes e não apenas aos bots ocupados. A aritmética é a mesma usada para dimensionar RAM e CPU para uma VPS com um agente de programação. O funcionamento do browser é explicado em executar um browser headless para agentes numa VPS.
Um detalhe do Chromium afeta os planos pequenos. O OpenBot inicia o Chromium com --disable-dev-shm-usage. Assim, o browser escreve em /tmp em vez de /dev/shm. Isto evita a falha que ocorre em hosts com um /dev/shm pequeno. No entanto, transfere a pressão para o sistema de ficheiros raiz. Esse é outro motivo para o disco recomendado ser maior do que a imagem.
Como alojar o OpenBot num VPS?
Precisa de Docker, Bun 1.3 ou mais recente, um projeto de Intelligence do CopilotKit e uma chave de API do modelo. A documentação de desenvolvimento também espera lsof, python3 e curl no servidor. Clone uma release identificada por uma tag em vez de main, porque main num projeto alpha muda sem aviso.
git clone --branch v0.0.1 https://github.com/CopilotKit/openbot.git
cd openbot
cp .env.example .envProvisione o projeto de Intelligence. Estes três comandos escrevem a chave de runtime e o token de licença no ficheiro de ambiente.
npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --writeGere a chave que cifra as credenciais armazenadas e coloque o resultado em .env como KEY_ENCRYPTION_KEY. Adicione o seu OPENAI_API_KEY ao mesmo ficheiro ou defina BOT_PROVIDER como anthropic ou google com a chave correspondente.
openssl rand -base64 32Depois, instale e inicie os serviços.
bun install
bash scripts/start.shscripts/start.sh inicia os serviços Docker, executa as migrações da base de dados, inicia o servidor e a aplicação e verifica o estado de saúde de ambos. Quando termina, a aplicação responde na porta 3010 e a API na porta 3001. O script comunica conflitos de portas e deixa em execução um serviço correspondente que já esteja ativo, por isso é seguro executá-lo duas vezes.
Verifique o serviço no próprio servidor antes de expor qualquer porta.
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3010
ss -ltnp | grep -E ':(3010|3001|4100|4500|5432)'Um 200 no primeiro comando significa que a aplicação está a responder. O segundo comando mostra a que endereços essas portas estão associadas, e essa é a informação relevante num VPS. Uma linha com 127.0.0.1:3001 indica que a porta está acessível apenas no servidor. Uma linha com 0.0.0.0:3001 significa que qualquer pessoa com uma rota de rede para o servidor pode aceder-lhe.
A imagem de contentor única
A documentação de deployment também fornece uma única imagem que contém a aplicação, a API e o Chromium, disponibilizada na porta 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 executa o PostgreSQL dentro do contentor e aplica as migrações no arranque. O volume nomeado preserva o histórico de auditoria entre redeployments. Sem esse volume, cada rebuild elimina esse histórico. Se apontar DATABASE_URL para uma base de dados gerida, a extensão vector tem de estar ativada nessa base de dados. Serviços geridos como RDS, Cloud SQL e Azure Database suportam a extensão, mas nenhum deles a ativa automaticamente. Por isso, uma migração para uma base de dados gerida nova falha porque o tipo de coluna vector ainda não existe.
Execute as migrações como uma etapa de release quando a base de dados for externa.
docker run --rm --env-file .env openbot \
sh -c "cd /app/server && bun x drizzle-kit migrate --config=drizzle.config.ts"Essa imagem deixa deliberadamente a porta do browser sem publicação. Também não inclui o supervisor, porque o supervisor precisa do socket do Docker, que as plataformas serverless não disponibilizam. Sem o supervisor, todos os bots partilham um browser e, portanto, o mesmo conjunto de logins. Isso elimina o isolamento que justificava executar contentores separados por bot. Se a necessidade de logins separados por bot é o motivo para estar a usar esta solução, execute a stack do compose com COMPUTER_SUPERVISOR_URL e SUPERVISOR_TOKEN definidos, num host onde aceite esse compromisso. Um processo que consiga comunicar com o socket do Docker pode iniciar um contentor privilegiado. Na prática, esse processo tem acesso root ao host. Essa é uma boa razão para manter o OpenBot numa máquina própria, seguindo o mesmo princípio de dar aos agentes de programação uma VM descartável.
Por que OPENBOT_SINGLE_USER é uma configuração para portáteis
.env.example é fornecido com OPENBOT_SINGLE_USER=true. Essa configuração aceita todos os pedidos como se fossem feitos por um único administrador e ignora completamente o início de sessão. Num portátil, isto é conveniente, porque o único cliente que consegue aceder à porta é o próprio utilizador. Num VPS, significa que a primeira pessoa que aceder à porta 3010 se torna administradora de um sistema que armazena credenciais cifradas e controla um browser com sessões iniciadas nas suas contas.
Existem duas formas seguras de o executar. Mantenha OPENBOT_SINGLE_USER=true, associe todas as portas a 127.0.0.1 e aceda à aplicação apenas através de um túnel SSH ou de uma interface de rede privada.
ssh -N -L 3010:127.0.0.1:3010 -L 3001:127.0.0.1:3001 you@your-vpsA aplicação fica disponível em http://localhost:3010 no seu próprio browser. Isto é considerado um contexto seguro, pelo que os cookies de início de sessão e as funcionalidades do browser de que o ecrã em tempo real precisa funcionam corretamente. A outra opção é desativar o modo de utilizador único e configurar um fornecedor de identidade real. Google, Microsoft Entra, Okta, SAML e OIDC são suportados. Qualquer fornecedor também precisa de BETTER_AUTH_SECRET com 32 caracteres ou mais, de BETTER_AUTH_URL definido como o URL público base da API para os callbacks OAuth, de INITIAL_ADMIN_EMAILS e de TRUSTED_ORIGINS. As credenciais do fornecedor têm de estar completas, porque um fornecedor configurado apenas parcialmente impede o arranque em vez de recuar para o acesso aberto. Se está a adicionar contas porque cada pessoa da equipa quer ter o seu próprio agente, e não apenas o seu próprio browser, OneCLI foi concebido desde o início para esse modelo, com um agente isolado numa sandbox por pessoa e as chaves dos modelos mantidas num único gateway.
Se a aplicação estiver acessível através de um nome público, coloque TLS (transport layer security) à sua frente. Uma página servida através de http:// simples, em qualquer endereço que não seja localhost, não é um contexto seguro. Por isso, os cookies marcados com Secure não são armazenados e o início de sessão falha de uma forma que parece ser um erro do OpenBot.
Bloqueie as portas de níveis inferiores
A própria nota de segurança do OpenBot afirma que os endpoints dos serviços de níveis inferiores estão protegidos por tokens, que devem ser mantidos privados e que não devem ser usados para contornar o gateway. Os tokens são a segunda proteção. A primeira é impedir completamente o acesso à porta.
O agent-computer escuta na porta 4100 e exige COMPUTER_TOKEN. Os endpoints do bot escutam nas portas 4200 e 4201. O supervisor escuta na porta 4500 no host e na porta 4300 dentro do seu contentor. O PostgreSQL escuta na porta 5432. Nenhum destes serviços deve estar numa interface pública. Numa implementação para um único utilizador, o mesmo se aplica à aplicação e à API.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verboseExiste uma armadilha que afeta quem presume que o firewall é suficiente. Publicar uma porta de contentor com -p 3001:3001 faz com que o Docker instale uma regra DNAT. Assim, o tráfego é processado no caminho FORWARD e nunca passa pela cadeia INPUT, que é abrangida pela política de negação predefinida do ufw. A porta continua aberta enquanto ufw status ainda apresentar Status: active. Associe a porta publicada ao loopback diretamente no mapeamento, como em -p 127.0.0.1:3001:3001, ou defina o endereço do host no seu ficheiro compose. Verifique com ss -ltnp, não com ufw status. Esta armadilha não é específica do OpenBot. Por isso, faça a mesma verificação em todos os outros contentores que publicou nesse servidor, incluindo o serviço que disponibiliza uma biblioteca Jellyfin reconstruída como uma videoteca dos anos 90.
O OpenBot não é uma stack offline
Defina isto antes de planear a implementação. O OpenBot depende de um projeto CopilotKit Intelligence, que armazena threads persistentes e a memória das conversas fora do seu servidor. O servidor valida INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL, INTELLIGENCE_API_KEY e COPILOTKIT_LICENSE_TOKEN no arranque, e os quatro têm de estar presentes em conjunto; caso contrário, o arranque falha. Existe um plano gratuito desde August 2026, e o próprio Intelligence pode ser alojado localmente. Por isso, é possível fazer uma implementação totalmente local, mas com mais trabalho do que o quickstart mostra.
O modelo é a segunda dependência externa. Nenhum modelo é fornecido com o sistema. BOT_PROVIDER aceita openai, anthropic ou google, e OPENAI_BASE_URL direciona o caminho OpenAI para qualquer endpoint compatível. É aqui que se enquadra executar Ollama numa VPS para alojar localmente um LLM, se quiser manter os tokens no seu próprio hardware. O controlo do browser exige bastante do modelo. Teste um modelo local numa tarefa real antes de o escolher.
Execute uma réplica, por enquanto
O gateway armazena instantâneos de páginas em cache na memória do processo do servidor. Com duas réplicas, um instantâneo obtido por um processo fica invisível para o outro. Por isso, as ações falham de forma intermitente com erros de elemento não encontrado que parecem aleatórios. A documentação de implementação é explícita: execute uma única réplica e fixe em 1 o número máximo de instâncias da sua plataforma. Esse limite deixa de ser necessário quando o armazenamento em cache dos instantâneos passar para a base de dados. Até lá, escale o OpenBot aumentando os recursos da máquina, e não adicionando máquinas. O isolamento entre bots continua a ser assegurado pelos contentores individuais de cada bot, tal como sandboxes de agentes autoalojados mantêm os erros de um agente afastados dos restantes.
Modos de falha e o que verá
O arranque termina imediatamente depois de preencher .env. O servidor valida a configuração antes de disponibilizar qualquer serviço. Um bloco Intelligence incompleto, a ausência de KEY_ENCRYPTION_KEY ou um fornecedor OAuth com um ID de cliente sem segredo fazem o arranque parar, em vez de falharem silenciosamente. Leia o primeiro erro, corrija esse campo e tente iniciar novamente.
As migrações falham numa base de dados gerida. A extensão vector não está ativada por predefinição, por isso a migração encontra um tipo de coluna que o PostgreSQL não reconhece. Ligue-se como superuser, execute CREATE EXTENSION vector; e repita o passo da migração.
A aplicação carrega, mas o início de sessão nunca fica ativo. Está a servir através de http:// simples num endereço público. Esse não é um contexto seguro, por isso o cookie Secure é descartado. Coloque TLS à frente da aplicação ou use o túnel SSH para que o navegador veja localhost.
Os bots partilham inícios de sessão que esperava que fossem separados. O supervisor não está em execução, por isso não existe um computador por bot e todos os bots usam o navegador partilhado. Confirme se COMPUTER_SUPERVISOR_URL está definido e se o supervisor consegue aceder ao socket do Docker.
Um bot para e pede ajuda. Isso indica que o sistema está a funcionar conforme concebido. O registo de auditoria grava computer.help_requested, assume o controlo no ecrã ativo e a transferência fica registada de ambos os lados.
FAQ
É seguro deixar OPENBOT_SINGLE_USER ativado numa implantação VPS?
Só quando o gateway não pode ser alcançado a partir da Internet. OPENBOT_SINGLE_USER=true aceita todos os pedidos como um único administrador, sem autenticação, pelo que qualquer pessoa que consiga abrir a porta controla a implantação, as credenciais armazenadas e o navegador com sessão iniciada. Isto é aceitável quando todas as portas estão associadas a 127.0.0.1 e a aplicação é acedida através de um túnel SSH ou de uma interface de rede privada. Numa interface pública, desative-o e configure Google, Microsoft Entra, Okta ou OIDC juntamente com BETTER_AUTH_SECRET, BETTER_AUTH_URL, INITIAL_ADMIN_EMAILS e TRUSTED_ORIGINS.
De quanta RAM precisa um bot OpenBot?
Os valores publicados pelo projeto para um único Bot em arm64 indicam um pico de memória de 0.55 GB, com 2 GB como mínimo documentado e 4 GB recomendados. Não existe um valor publicado para vários bots em simultâneo, porque cada um mantém o seu próprio Chromium. Execute um bot numa tarefa real, consulte a memória desse contentor em docker stats, some o gateway e a base de dados e, em seguida, multiplique pelo número de bots que espera ter em execução ao mesmo tempo.
Preciso de uma conta CopilotKit para alojar o OpenBot localmente?
Sim. O OpenBot depende de um projeto CopilotKit Intelligence para manter threads e memória, e o servidor recusa iniciar enquanto o URL da API Intelligence, o URL WebSocket do gateway, a chave da API e o token de licença não estiverem todos definidos. Existe um plano gratuito em agosto de 2026, e o Intelligence pode ser alojado localmente, pelo que é possível remover essa dependência alojada com trabalho adicional. Também deve fornecer a sua própria chave da API do modelo, porque o OpenBot não inclui nenhum modelo.
Por que motivo cada bot recebe o seu próprio navegador em vez de partilhar um?
Porque um perfil de navegador é uma identidade. Um navegador partilhado significa cookies e sessões partilhados, pelo que um bot com sessão iniciada numa conta faz com que todos os bots tenham sessão iniciada nessa conta. Os contentores separados por bot dão a cada colaborador o seu próprio perfil e os seus próprios inícios de sessão. O custo é a memória, porque um Chromium por bot é o maior componente individual do dimensionamento.
Que portas do OpenBot devem estar abertas na firewall?
Nenhuma das portas de nível inferior. O agent-computer em 4100, os endpoints dos bots em 4200 e 4201, o supervisor em 4500 e o PostgreSQL em 5432 devem permanecer privados. O projeto protege-os com tokens e recomenda que continue a impedir o acesso a eles. Publique apenas o que uma pessoa precisa de abrir e lembre-se de que uma porta de contentor publicada com -p 3001:3001 pode ser alcançada independentemente de uma regra ufw default-deny, porque a regra DNAT do Docker coloca esse tráfego no caminho FORWARD, em vez de INPUT.