SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor

Como alojar o Dormice para sandboxes de agentes

Instale o Dormice num VPS Linux, execute codigo nao confiavel com uma API compativel com E2B, verifique o isolamento e calcule o dimensionamento do host.

O que é o Dormice e o que não é

O Dormice é um sandbox de agentes autoalojado: um daemon num VPS Linux que lhe pertence, ao qual o código do seu agente faz chamadas HTTP para executar código não confiável dentro de um contentor isolado. O seu programa pede um sandbox pelo nome, recebe o mesmo sandbox independentemente do estado em que estava, executa um comando dentro dele e lê o resultado. O sandbox é um recurso programático, não uma máquina na qual inicia sessão.

Isto é diferente de dar ao agente um computador inteiro. Uma VM descartável para um agente de programação é uma máquina à qual se liga por SSH, deixa o agente danificar e depois elimina. O Dormice fica um nível abaixo: é a API de execução que o seu programa chama quando já tem código e precisa de um local seguro para o executar. Use a VM descartável quando uma máquina inteira for a unidade de trabalho. Use o Dormice quando uma única chamada exec for a unidade de trabalho e quiser fazer cem por dia sem cem VMs.

O projeto declara compatibilidade com E2B. O E2B é um serviço de sandbox alojado cuja biblioteca cliente muitos frameworks de agentes já importam. O Dormice disponibiliza o mesmo protocolo nos seus próprios prefixos de URL, por isso uma aplicação escrita para o pacote e2b oficial continua a funcionar quando aponta para a sua própria máquina. O código da aplicação não muda. Apenas mudam 2 URLs e 1 prefixo de chave de API.

O que significa, na prática, "o SQLite dos sandboxes de agentes"

O SQLite é uma base de dados que integra, em vez de um serviço que tem de operar, e o Dormice usa diretamente essa comparação. Um daemon, um ficheiro SQLite para o ledger e uma porta TCP. Sem Kubernetes, sem uma base de dados separada e sem um scheduler. O daemon bloqueia o acesso junto ao seu ledger e recusa iniciar quando o ledger e a máquina que encontra não podem pertencer ao mesmo sistema. Assim, não pode ocorrer silenciosamente um split brain. O design pressupõe uma máquina. Se precisar de uma frota distribuída por vários hosts, o README recomenda claramente que escolha outra solução, e deve seguir essa recomendação.

A segunda parte da ideia está relacionada com o custo. Um sandbox alojado é faturado por cada segundo em que existe, pelo que os sandboxes alojados são descartáveis por design. O Dormice é executado em hardware que já paga, por isso os seus sandboxes são permanentes e ficam mais baratos quanto mais tempo permanecerem inativos. Um sandbox desce um nível de cada vez: ativo, depois congelado, depois parado e, por fim, arquivado. Qualquer acquire volta a ativá-lo a partir do nível em que ficou.

O congelamento é a parte que importa compreender, porque permite manter permanentemente o sandbox de cada agente a um custo acessível. Estes são os valores publicados pelo próprio projeto, medidos no hardware do projeto e não no seu.

ChartOne idle sandbox before and after freezing, figures published by the project
The data behind this chart
[
  {
    "label": "Active, holding 1 GiB",
    "resident_memory_mib": 1024,
    "wake_ms": 0
  },
  {
    "label": "Frozen",
    "resident_memory_mib": 5,
    "wake_ms": 50
  }
]

Um sandbox inativo que utiliza 1024 MiB de memória passa a ocupar 5 MiB de memória residente depois de ser congelado e volta a estar disponível em cerca de 50 ms. Os processos são suspensos e retomados no mesmo estado, pelo que um agente de longa duração mantém o estado da shell e o trabalho parcialmente concluído durante o congelamento. Reproduza este comportamento no seu próprio host antes de planear a capacidade com base nele.

O que o host precisa antes da instalação

O host deve executar Ubuntu ou Debian em x86_64, e o instalador precisa de root. O daemon mantém o root durante a execução porque faz loop mounts e escreve em cgroups.

Os sandboxes executam no Docker com gVisor (um runtime de contentores que coloca um kernel em espaço de utilizador entre o contentor e o kernel do host), que fornece o runtime runsc usado por cada sandbox. O Node 22 ou mais recente executa o daemon, e o instalador inclui a sua própria cópia. O Node do sistema não é alterado.

Tem de existir swap, e vm.swappiness tem de ser 100. Isto não é uma recomendação de otimização. É um requisito funcional. O congelamento funciona ao transferir para a swap a memória de um sandbox inativo. O gVisor mantém a memória do sandbox como memória partilhada, e o kernel não troca memória partilhada para a swap com o valor predefinido de swappiness. O projeto mediu 0 bytes recuperados com o valor predefinido e 99.5 por cento recuperados com 100. Verifique o valor que o kernel está realmente a utilizar, porque algumas imagens de cloud definem vm.swappiness = 0 num ficheiro que normalmente não se lembraria de consultar.

sysctl vm.swappiness
swapon --show

sysctl vm.swappiness deve apresentar vm.swappiness = 100, e swapon --show deve listar um swapfile. Se swappiness apresentar 0, cada congelamento não terá efeito e continuará a pagar a memória total de cada sandbox inativo.

Instalar o Dormice no Ubuntu

A instalação documentada consiste num pipe para bash:

curl -fsSL https://raw.githubusercontent.com/BitMiracle-AI/Dormice/main/deploy/install.sh | bash

Transfira o script e leia-o antes de o executar. Este script é executado como root e altera o host: instala o Docker se este não estiver instalado, transfere o gVisor e o Caddy com verificação de checksum, cria um swapfile, escreve unidades systemd e adiciona regras de firewall.

curl -fsSL https://raw.githubusercontent.com/BitMiracle-AI/Dormice/main/deploy/install.sh -o dormice-install.sh
less dormice-install.sh
sudo bash dormice-install.sh --swap-gb 8

--swap-gb define o tamanho do swapfile e, por predefinição, usa 16, o que representa muito espaço em disco num VPS pequeno. --mirror cn muda as transferências para mirrors acessíveis a partir da China continental. Executar novamente o instalador atualiza o código e corrige divergências, mas nunca roda o seu token de API.

O código é colocado em /opt/dormice, a configuração em /etc/dormice/env, os dados do sandbox em /var/lib/dormice, e os comandos dormice e dor em /usr/local/bin. O instalador gera o token de API durante a instalação e escreve-o em /etc/dormice/env com o modo 600.

Não existe uma release identificada para instalar. Em 4 de agosto de 2026, o repositório não tinha tags git nem releases no GitHub, por isso o instalador clona main e instala o que tiver sido incorporado nessa manhã. Fixar uma versão significa, portanto, registar o commit que foi efetivamente instalado.

git -C /opt/dormice rev-parse HEAD

Guarde esse hash juntamente com as notas da implementação. Se uma atualização causar problemas, esse commit é a única forma de voltar atrás, porque não existe um número de versão que possa consultar.

O instalador termina executando dor doctor, uma verificação do host apenas de leitura que inicia contentores gVisor reais para confirmar que o runtime funciona, em vez de confiar numa lista de pacotes. Execute-a novamente sempre que o daemon apresentar problemas.

sudo dor doctor
systemctl is-active dormice

systemctl is-active dormice deve apresentar active. Se apresentar failed, journalctl -u dormice -n 50 contém o motivo, e uma falha no arranque costuma estar relacionada com o swap ou com um pré-requisito do gVisor, não com o daemon em si.

O instalador também instala o Caddy no host. Por isso, verifique o que está a escutar antes de considerar concluído o trabalho do firewall.

sudo ss -lntp

O daemon associa-se a 127.0.0.1:3676 e, por definição, não existe uma configuração para alterar esse comportamento. Aceder-lhe a partir do seu portátil é uma ação deliberada. A opção mais simples é um túnel SSH.

ssh -L 3676:127.0.0.1:3676 root@your-server

Com o túnel aberto, http://127.0.0.1:3676/console no seu portátil é a consola Web. Autentique-se uma vez com o token. Depois disso, o token é convertido num cookie de sessão httpOnly, por isso não fica armazenado num local que a página possa ler. A página Connect apresenta snippets de cliente prontos para copiar e colar, já apontados para o seu próprio endpoint.

Crie um sandbox e execute código nele

Uma operação cria um sandbox: acquire. Ela é idempotente, portanto a mesma chave devolve sempre o mesmo sandbox, criando-o, reativando-o, iniciando-o ou restaurando-o conforme necessário. Todos os outros verbos respondem com 404 para uma chave que nunca foi utilizada. A CLI dor não tem o verbo acquire, por isso o primeiro sandbox é criado na consola ou através de uma biblioteca cliente.

A rota da consola é a mais rápida. Abra /console através do túnel e crie um sandbox com o nome my-agent. A CLI passa então a operar nele.

sudo grep DORMICE_API_TOKEN /etc/dormice/env
export DORMICE_ENDPOINT=http://127.0.0.1:3676
export DORMICE_API_TOKEN=paste-the-value-here
dor sandbox ls
dor sandbox exec my-agent 'python3 --version'

dor sandbox ls lista cada sandbox com o respetivo estado do ciclo de vida. É assim que pode monitorizar a passagem de um estado ativo para congelado. dor sandbox exec apresenta uma versão do Python 3.12, porque a imagem padrão é Ubuntu 24.04, com Python 3.12, Node 24, git e ripgrep já instalados. Um erro de autenticação significa, em vez disso, que a linha do token copiada incluía o nome da variável.

Os ficheiros são transferidos com dor sandbox push my-agent ./script.py, que os coloca em /home/user/script.py, e dor sandbox pull my-agent notes.txt recupera um ficheiro. Os verbos nativos para ficheiros limitam cada ficheiro a 16 MiB, enquanto a interface de ficheiros do E2B faz streaming e permite que a quota de disco do sandbox seja o único limite.

A destruição é o único verbo que elimina dados. Também é um bom exemplo da antiguidade do projeto: o README principal e a capacidade de agente incluída documentam dor sandbox destroy <key>, enquanto o README do pacote da CLI documenta dor sandbox release <key>. Execute dor sandbox --help na sua própria compilação e considere esse resultado como a referência.

Aponte o seu código E2B existente para o seu próprio servidor

Este é o motivo para utilizar esta solução. O pacote oficial e2b do npm, sem alterações, comunica com o Dormice. Execute isto no seu portátil com o túnel SSH aberto, para que nada novo fique a escutar no servidor.

npm init -y
npm i e2b tsx
import { Sandbox } from 'e2b';

const sbx = await Sandbox.create({
  apiKey: `e2b_${process.env.DORMICE_API_TOKEN}`,
  apiUrl: 'http://127.0.0.1:3676/e2b/api',
  sandboxUrl: 'http://127.0.0.1:3676/e2b/envd',
});

const result = await sbx.commands.run('python3 -c "print(6 * 7)"');
console.log(result.exitCode, result.stdout);

await sbx.kill();
DORMICE_API_TOKEN=paste-the-value-here npx tsx index.ts

Uma execução normal apresenta o código de saída 0 e 42. A chave da API é o seu token do Dormice com o prefixo e2b_, que é o formato esperado pela camada de compatibilidade.

A compatibilidade não é apenas um stub. O suite de testes end-to-end do projeto testa o stdout e o stderr em fluxo, os comandos em segundo plano, um PTY interativo, os URLs assinados para upload e download, a monitorização de diretórios e um proxy de portas através do pacote oficial, contra daemons reais do Docker e do gVisor. Antes de migrar qualquer carga real, tenha em conta algumas diferenças:

  • As compilações de templates não estão implementadas. Um template é uma imagem Docker que cria e regista com dor template add, e Sandbox.create('name') resolve essa imagem. Um nome não registado devolve 404, em vez de ser aceite incorretamente.
  • Os sandboxes criados através da interface E2B têm deadlines reais, porque a semântica do E2B os exige. Não são impostos deadlines aos sandboxes criados através da API nativa.
  • Um sandbox congelado mantém os seus processos e retoma a execução no ponto em que estavam. Por isso, a pausa e a retoma aqui não correspondem à paragem e ao arranque a frio a que pode estar habituado.

O que o sandbox impede e o que não impede

O gVisor interceta as chamadas de sistema do contentor no espaço do utilizador e trata-as internamente. Assim, o código no sandbox não comunica diretamente com o kernel do host. Dentro do sandbox, tudo é executado como um utilizador sem privilégios, uid 1000. Esta combinação trata o caso normal: um script gerado que execute rm -rf /, encha o disco ou crie processos até algo falhar danifica o próprio sandbox e fica limitado a esse ambiente.

Isto é o que não impede. Cada um destes pontos é da sua responsabilidade.

  • Um sandbox tem rede de saída funcional. O código gerado pode descarregar o que quiser e enviar tudo o que encontrar. O reforço de segurança da instalação cobre duas situações específicas: bloqueia o tráfego dos contentores para o serviço de metadados da cloud em 169.254.0.0/16, que é onde a cloud disponibiliza as credenciais da instância a qualquer processo que consiga aceder-lhe, e desativa o tráfego entre contentores com "icc": false em daemon.json do Docker. Nada mais é bloqueado. Leia sudo iptables -S DOCKER-USER e adicione as suas próprias regras DROP para os intervalos privados que um sandbox não deve conseguir alcançar.
  • O Docker insere as suas próprias regras antes da firewall. Por isso, uma porta publicada do contentor pode responder a partir da Internet enquanto o ufw indica que está fechada. Leia como o Docker publica portas através do ufw e os fundamentos da firewall ufw para um VPS antes de expor qualquer serviço neste host.
  • O gVisor é um kernel no espaço do utilizador, não um hypervisor. Esta é uma limitação deliberada, porque o isolamento exige que os sandboxes sejam processos, e exigir KVM impediria a instalação em muitos ambientes. Se o seu modelo de ameaças exigir virtualização assistida por hardware, use isolamento da classe do Firecracker e aceite o custo operacional associado.
  • O token da API é toda a fronteira de segurança do lado do cliente. Qualquer processo que tenha DORMICE_API_TOKEN pode criar, ler e destruir todos os sandboxes da máquina. Dê ao processo do agente o seu próprio utilizador com privilégios mínimos no VPS e trate o token como trataria uma chave SSH. As práticas de executar Claude Code com segurança num VPS aplicam-se diretamente.

O daemon é executado como root no host. O gVisor protege o host contra o código dentro de um sandbox. Nada protege o host contra o daemon ou contra quem possuir o token. Por isso, a máquina que executa o Dormice deve ser dedicada exclusivamente a essa função. Se o seu agente também aceder a ferramentas através de MCP (model context protocol), mantenha esses servidores MCP num VPS separado pelo mesmo motivo.

Quantos sandboxes cabem em 4 GB e 8 GB?

Duas coisas consomem memória: a utilização base do host e o conjunto de trabalho de cada sandbox que está atualmente ativo. Reserve cerca de 1 GB para o Ubuntu, o Docker e o daemon. Depois, divida o que restar pelo consumo real de um dos seus sandboxes. Um sandbox que executa um script Python que lê alguns ficheiros utiliza cerca de 200 a 300 MiB. Um sandbox que executa um compilador ou uma suite de testes completa pode ultrapassar 1 gibibyte.

ChartConcurrent sandboxes by host RAM, arithmetic after a 1 GB host reserve
The data behind this chart
[
  {
    "host": "4 GB VPS",
    "active_at_512_mib": 6,
    "active_at_1_gib": 3,
    "frozen_on_16gb_swap": 16
  },
  {
    "host": "8 GB VPS",
    "active_at_512_mib": 14,
    "active_at_1_gib": 7,
    "frozen_on_16gb_swap": 16
  }
]

Um VPS com 4 GB suporta cerca de 6 sandboxes ativos em simultâneo se cada um utilizar 512 MiB, ou 3 se cada um utilizar 1 gibibyte completo. Num VPS com 8 GB, esses valores passam para 14 e 7. Estes são limites para trabalho concorrente, calculados por aritmética e não por um benchmark. Por isso, monitorize free -m enquanto executa a sua própria carga.

Os sandboxes congelados ficam limitados pelo swap e não pela RAM. Esse é o objetivo deste desenho. Um sandbox congelado que estava a utilizar 1 gibibyte mantém aproximadamente essa quantidade no swap e quase nada na memória residente. Assim, o swapfile predefinido de 16 GB do instalador mantém cerca de 16 desses sandboxes. Depois disso, eles precisam de passar para o estado parado, no qual consomem apenas espaço em disco. O disco é o limite real a longo prazo: cada sandbox mantém o seu sistema de ficheiros, e algumas dezenas de agentes, cada um com um diretório node_modules, vão preencher um volume pequeno muito antes de a memória se tornar um problema.

Congelar, parar, arquivar: parâmetros do ciclo de vida

Os valores predefinidos são congelar após 10 minutos de inatividade, parar após 3 dias e arquivar após 7 dias quando o arquivamento está configurado. Definir stopAfterSeconds como null cria um agente residente: pode congelar quando está inativo, mas nunca faz um arranque a frio.

O arquivamento é opcional, e o daemon informa claramente o estado. Defina as quatro variáveis DORMICE_S3_* para que o disco de um sandbox parado seja compactado com tar e zstd, enviado para qualquer bucket compatível com S3 e libertado localmente. Esse bucket pode ser um bucket MinIO alojado por si noutra máquina sua. Se deixar as variáveis por definir, os sandboxes permanecem parados indefinidamente, e uma política que peça o arquivamento é recusada em vez de ser silenciosamente ignorada. Os restauros são visíveis: a próxima aquisição responde imediatamente com um estado de restauro e um valor de progresso. Depois, passa para pronto quando o disco estiver novamente disponível.

Já deve depender dele?

Resposta direta: não para nada que não consiga reconstruir. O primeiro commit no repositório é de 8 July 2026. Em 4 August 2026, o projeto tinha 446 stars, 37 forks, uma licença Apache-2.0 e nenhuma release identificada. A própria linha de estado do README diz que nada está pronto para produção.

Essa combinação cria um risco específico. O código pode mudar sem aviso, porque o instalador acompanha main. A interface ainda está a estabilizar. É por isso que o verbo de eliminação tem dois nomes diferentes em dois ficheiros do mesmo repositório. Além disso, um projeto com quatro semanas pode simplesmente ser abandonado, porque nenhuma cláusula da licença obriga alguém a continuar o desenvolvimento.

A compatibilidade com E2B torna o risco controlável. A sua aplicação comunica com um protocolo que tem uma implementação alojada. Assim, se o Dormice parar, pode alterar dois URLs e continuar a trabalhar. Desenvolva o seu agente sobre a interface E2B em vez da API nativa para preservar essa alternativa. O pacote nativo @dormice/sdk também ainda não está disponível no npm. Para o utilizar, terá de o compilar a partir do repositório. Esse é outro motivo para começar pelo caminho compatível.

Execute-o onde possa aceitar perder o ambiente. Reconstrua o host a partir de um script, mantenha o token fora de todos os prompts e commits e retire das sandboxes qualquer conteúdo que valha a pena conservar, seguindo o seu próprio calendário de backups.

FAQ

O Dormice está pronto para produção?

Não, e o próprio projeto afirma isso. A linha de estado do README indica que nada ali está pronto para produção, e, em 4 August 2026, o repositório tinha cerca de quatro semanas, sem tags git nem releases. Portanto, não existe um número de versão que possa ser fixado. O instalador clona o branch main, o que significa que cada execução obtém o commit mais recente. Registe git -C /opt/dormice rev-parse HEAD após cada instalação e mantenha tudo o que for importante fora dos sandboxes.

Em que o Dormice é diferente de dar ao meu agente uma VM descartável?

Uma VM descartável é uma máquina com SSH que cria para uma sessão e elimina depois. O Dormice é uma API de execução: o programa chama acquire, depois exec, e recebe de volta o stdout e um código de saída, sem uma sessão de shell intermediária. A VM é adequada para uma pessoa ou agente que precise de um computador completo durante algum tempo. O Dormice é adequado para uma aplicação que execute código gerado várias vezes por dia e não queira repetir a preparação e a remoção de uma máquina a cada execução.

O SDK oficial do E2B funciona mesmo sem alterações no código?

Sim, com alterações de configuração. Aponte apiUrl e sandboxUrl para /e2b/api e /e2b/envd no daemon e passe o token do Dormice como chave da API, com o prefixo e2b_. A execução de comandos, as sessões PTY, a transferência de ficheiros, os URLs assinados e o proxy de portas estão todos abrangidos pela suite end-to-end do projeto, executada através do pacote oficial. A criação de templates é a principal lacuna: e2b template build não está implementado, por isso um template é uma imagem Docker que cria e regista com dor template add.

Quantos sandboxes cabem num VPS de 4 GB?

Cerca de 6 ativos ao mesmo tempo se cada sandbox usar 512 MiB, ou 3 se cada um usar um gibibyte completo, depois de reservar aproximadamente 1 GB para o sistema operativo, o Docker e o daemon. Os sandboxes congelados são limitados pelo swap. Portanto, o swapfile predefinido de 16 GB do instalador mantém cerca de 16 sandboxes que tenham usado 1 gibibyte cada. Faça as suas próprias medições com free -m sob carga real, porque um sandbox que execute uma suite de testes usa várias vezes mais memória do que um que execute um script pequeno.

Por que o Dormice precisa de vm.swappiness definido como 100?

Congelar um sandbox significa transferir a memória inativa desse sandbox para o swap. O gVisor mantém a memória do sandbox como memória partilhada, e o kernel Linux não coloca memória partilhada no swap com o valor predefinido de swappiness. Assim, com o valor predefinido, o congelamento não recupera memória e o sandbox continua a consumir a memória total. O projeto mediu 0 bytes recuperados com o valor predefinido e 99.5 por cento com o valor 100. Verifique o valor efetivo com sysctl vm.swappiness em vez de ler ficheiros de configuração, porque algumas imagens de cloud são fornecidas com o valor 0.