SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor

Cómo autohospedar Dormice para sandboxes de agentes

Instale Dormice en un VPS Linux, ejecute código no confiable con una API compatible con E2B, compruebe el aislamiento y calcule los recursos del host.

Qué es Dormice y qué no es

Dormice es un sandbox de agentes autohospedado: un daemon en un VPS Linux que usted administra. El código de su agente lo invoca mediante HTTP para ejecutar código no confiable dentro de un contenedor aislado. El programa solicita un sandbox por nombre, obtiene el mismo sandbox independientemente de su estado anterior, ejecuta un comando dentro de él y lee la salida. El sandbox es un recurso programático, no una máquina a la que se accede mediante login.

Esto es distinto de proporcionar a un agente un equipo completo. Una VM desechable para un agente de programación es un sistema al que se accede mediante SSH, se deja que el agente lo modifique o dañe y después se elimina. Dormice se sitúa un nivel por debajo: es la API de ejecución que el programa invoca cuando ya dispone del código y necesita un entorno seguro donde ejecutarlo. Use la VM desechable cuando la unidad de trabajo sea una máquina completa. Use Dormice cuando la unidad de trabajo sea una sola llamada exec y quiera realizar cien al día sin crear cien VM.

El proyecto se declara compatible con E2B. E2B es un servicio de sandbox alojado cuya biblioteca cliente ya importan muchos frameworks de agentes. Dormice proporciona el mismo protocolo bajo sus propios prefijos de URL. Por tanto, una aplicación escrita para el paquete oficial e2b sigue funcionando cuando se configura para usar su propio servidor. El código de la aplicación no cambia. Sólo cambian dos URL y un prefijo de clave de API.

Qué significa en la práctica «el SQLite de los entornos aislados para agentes»

SQLite es una base de datos que se integra en la aplicación, no un servicio que haya que operar, y Dormice adopta directamente esa comparación. Un daemon, un archivo SQLite para el registro y un puerto TCP. No hay Kubernetes, ni una base de datos independiente ni un planificador. El daemon bloquea el archivo situado junto a su registro y no se inicia si el registro y la máquina que encuentra no pueden corresponderse, de modo que no puede producirse silenciosamente un cerebro dividido. El diseño está pensado para una sola máquina. Si necesita un conjunto de máquinas distribuidas entre varios hosts, el README le indica claramente que elija otra opción, y conviene hacerle caso.

La segunda parte de la idea se refiere al coste. Un entorno aislado alojado se factura por cada segundo que existe, por lo que estos entornos están diseñados para ser desechables. Dormice se ejecuta en hardware que ya paga, así que sus entornos aislados son permanentes y resultan más baratos cuanto más tiempo permanecen inactivos. Un entorno aislado baja un nivel cada vez: activo, congelado, detenido y archivado. Cualquier operación acquire lo recupera desde el nivel que haya alcanzado.

La congelación es la parte que conviene entender, porque permite conservar para siempre el entorno aislado de cada agente con un coste asequible. Estas son las cifras publicadas por el propio proyecto, medidas en su hardware y no en el suyo.

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
  }
]

Un entorno aislado inactivo que mantiene 1024 MiB de memoria desciende a 5 MiB de memoria residente cuando se congela y vuelve a estar disponible en aproximadamente 50 ms. Los procesos se suspenden y reanudan en el mismo lugar, por lo que un agente de larga duración conserva el estado de su shell y el trabajo a medio terminar durante la congelación. Reprodúzcalo en su propio host antes de planificar la capacidad basándose en estos datos.

Requisitos del host antes de la instalación

El host debe ejecutar Ubuntu o Debian en x86_64, y el instalador necesita root. El daemon mantiene root durante la ejecución porque realiza montajes de loop y escribe en cgroups.

Los entornos aislados se ejecutan con Docker y gVisor, un runtime de contenedores que coloca un kernel en espacio de usuario entre el contenedor y el kernel del host. Este proporciona el runtime runsc que utiliza cada entorno aislado. El daemon se ejecuta con Node 22 o posterior. El instalador incluye su propia copia, por lo que no modifica el Node del sistema.

Debe existir swap y vm.swappiness debe ser 100. No es una recomendación de ajuste: es un requisito funcional. La congelación funciona al expulsar a swap la memoria de un entorno aislado inactivo. gVisor mantiene la memoria del entorno aislado como memoria compartida, y el kernel no intercambia memoria compartida con el valor predeterminado de swappiness. El proyecto midió 0 bytes recuperados con el valor predeterminado y un 99.5 por ciento con el valor 100. Compruebe el valor que utiliza realmente el kernel, porque algunas imágenes de nube proporcionan vm.swappiness = 0 en un archivo que normalmente no se revisa.

sysctl vm.swappiness
swapon --show

sysctl vm.swappiness debería mostrar vm.swappiness = 100, y swapon --show debería listar un archivo de swap. Si swappiness muestra 0, cada congelación no hará nada y tendrá que reservar toda la memoria para cada entorno aislado inactivo.

Instalar Dormice en Ubuntu

La instalación documentada consiste en ejecutar una tubería hacia bash:

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

Descárguelo y léalo antes de ejecutarlo. Este script se ejecuta como root y modifica el host: instala Docker si falta, descarga gVisor y Caddy con verificación de sumas de comprobación, crea un archivo de swap, escribe unidades de systemd y añade reglas 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 establece el tamaño del archivo de swap y, de forma predeterminada, usa 16, que consume demasiado espacio en disco en un VPS pequeño. --mirror cn cambia las descargas a réplicas accesibles desde China continental. Si vuelve a ejecutar el instalador, actualiza el código y corrige las diferencias de configuración. Nunca cambia el token de API.

El código se instala en /opt/dormice, la configuración en /etc/dormice/env, los datos del sandbox en /var/lib/dormice y los comandos dormice y dor en /usr/local/bin. El instalador genera el token de API durante la instalación y lo escribe en /etc/dormice/env con permisos 600.

No existe ninguna versión etiquetada contra la que instalar. A fecha de 4 August 2026, el repositorio no contiene etiquetas de git ni versiones de GitHub. Por tanto, el instalador clona main y obtiene lo que se haya incorporado esa mañana. Fijar una versión significa anotar el commit que se instaló realmente.

git -C /opt/dormice rev-parse HEAD

Guarde ese hash junto con las notas del despliegue. Si una actualización rompe algo, ese commit es la única forma de volver atrás, porque no existe un número de versión que se pueda solicitar.

El instalador termina ejecutando dor doctor, una comprobación del host que sólo lee datos y arranca contenedores reales de gVisor para demostrar que el runtime funciona, en lugar de confiar en una lista de paquetes. Vuelva a ejecutarlo cuando el daemon no se comporte correctamente.

sudo dor doctor
systemctl is-active dormice

systemctl is-active dormice debería mostrar active. Si muestra failed, journalctl -u dormice -n 50 contiene el motivo. Un arranque fallido suele deberse al requisito de swap o de gVisor, no al daemon.

El instalador también instala Caddy en el equipo. Por eso, compruebe qué está escuchando antes de dar por terminado el trabajo del firewall.

sudo ss -lntp

El daemon se enlaza a 127.0.0.1:3676 y no tiene ninguna opción para cambiarlo. Es intencionado. Acceder a él desde el portátil requiere una acción explícita. La opción sencilla es un túnel SSH.

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

Con el túnel abierto, http://127.0.0.1:3676/console en el portátil es la consola web. Inicie sesión una vez con el token. Después se convierte en una cookie de sesión httpOnly, por lo que la página nunca puede leer ni almacenar el token. La página Connect muestra fragmentos de cliente listos para copiar y pegar, ya configurados para apuntar al endpoint propio.

Crear un sandbox y ejecutar código en él

Una operación crea un sandbox: acquire. Es idempotente, por lo que la misma clave siempre devuelve el mismo sandbox. Lo crea, lo activa, lo inicia o lo restaura según sea necesario. Cualquier otro verbo devuelve 404 para una clave que nunca haya visto. La CLI de dor no tiene el verbo acquire, por lo que el primer sandbox se obtiene desde la consola o desde una biblioteca cliente.

La ruta de la consola es la más rápida. Abra /console mediante el túnel y cree un sandbox llamado my-agent. Después, la CLI puede trabajar con él.

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 muestra cada sandbox con su estado del ciclo de vida. Así puede monitorizar cómo uno pasa de activo a congelado. dor sandbox exec muestra una versión de Python 3.12, porque la imagen estándar es Ubuntu 24.04 e incluye Python 3.12, Node 24, git y ripgrep. Un error de autenticación significa, en cambio, que la línea del token copiada incluía el nombre de la variable.

Los archivos se transfieren con dor sandbox push my-agent ./script.py, que los coloca en /home/user/script.py, y dor sandbox pull my-agent notes.txt recupera uno. Los verbos de archivos nativos limitan cada archivo a 16 MiB, mientras que la interfaz de archivos de E2B permite transmitirlos y deja que la cuota de disco del sandbox sea el único límite.

La destrucción es el único verbo que elimina datos. También es un ejemplo claro de la antigüedad del proyecto: el README principal y la capacidad de agente incluida documentan dor sandbox destroy <key>, mientras que el README del paquete de la CLI documenta dor sandbox release <key>. Ejecute dor sandbox --help en su propia compilación y use ese resultado.

Dirija su código E2B existente a su propio servidor

Este es el motivo para usarlo. El paquete oficial e2b de npm, sin modificar, se comunica con Dormice. Ejecútelo desde su portátil con el túnel SSH abierto, para que no se abra ningún puerto nuevo en el 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

Una ejecución correcta muestra el código de salida 0 y 42. La clave de API es su token de Dormice con el prefijo e2b_ delante, que es el formato que espera la capa de compatibilidad.

La compatibilidad no es un simple stub. La salida estándar y de error en streaming, los comandos en segundo plano, una PTY interactiva, las URL firmadas de carga y descarga, la supervisión de directorios y un proxy de puertos se prueban mediante el paquete oficial contra daemons reales de Docker y gVisor en la suite de extremo a extremo del proyecto. Antes de migrar algo real, tenga en cuenta varias diferencias:

  • Las compilaciones de plantillas no están implementadas. Una plantilla es una imagen de Docker que debe compilar usted mismo y registrar con dor template add, y Sandbox.create('name') la resuelve. Un nombre no registrado devuelve 404 en lugar de simular que existe.
  • Los sandboxes creados mediante la interfaz de E2B tienen plazos reales, porque la semántica de E2B los requiere. Los sandboxes creados mediante la API nativa nunca tienen plazos impuestos.
  • Un sandbox congelado conserva sus procesos y los reanuda en el punto en que estaban. Por tanto, la pausa y reanudación no equivalen aquí a detenerlo y arrancarlo desde cero, como puede ocurrir en otros entornos.

Qué bloquea el sandbox y qué no

gVisor intercepta las llamadas al sistema del contenedor en el espacio de usuario y las gestiona por sí mismo. Por tanto, el código aislado no se comunica directamente con el kernel del host. Dentro del sandbox, todo se ejecuta con un usuario sin privilegios, uid 1000. Esta combinación cubre el caso habitual: si un script generado ejecuta rm -rf /, llena el disco o crea procesos hasta provocar un fallo, el daño queda limitado a su propio sandbox.

Esto es lo que no bloquea. Cada uno de estos aspectos es responsabilidad suya.

  • El sandbox tiene acceso de salida a la red. El código generado puede descargar cualquier contenido y enviar cualquier dato que encuentre. El endurecimiento de red del instalador cubre dos aspectos concretos: bloquea el tráfico de los contenedores hacia el servicio de metadatos de la nube en 169.254.0.0/16, que es donde la nube entrega las credenciales de la instancia a cualquier proceso que pueda acceder a él, y desactiva el tráfico entre contenedores mediante "icc": false en daemon.json de Docker. No se bloquea nada más. Consulte sudo iptables -S DOCKER-USER y añada sus propias reglas DROP para los rangos privados a los que un sandbox no debería acceder.
  • Docker inserta sus propias reglas antes que el firewall. Por eso, un puerto publicado del contenedor puede responder desde Internet aunque ufw indique que está cerrado. Consulte cómo Docker publica puertos pasando por alto ufw y los fundamentos del firewall ufw para un VPS antes de exponer nada en este host.
  • gVisor es un kernel en el espacio de usuario, no un hipervisor. Es una decisión deliberada: para poder congelar los sandboxes, estos deben ser procesos, y exigir KVM impediría instalarlo en muchos entornos. Si su modelo de amenazas exige virtualización mediante hardware, use un aislamiento de la clase de Firecracker y asuma el coste operativo correspondiente.
  • El token de API es todo el límite de seguridad en el lado del cliente. Cualquier proceso que tenga DORMICE_API_TOKEN puede crear, leer y destruir todos los sandboxes de la máquina. Asigne al proceso del agente su propio usuario con privilegios mínimos en el VPS y trate el token como trataría una clave SSH. Las prácticas de ejecutar Claude Code de forma segura en un VPS se aplican directamente.

El daemon se ejecuta como root en el host. gVisor protege el host frente al código que se ejecuta dentro de un sandbox, pero nada protege el host frente al daemon ni frente a quien tenga su token. Por tanto, la máquina que ejecuta Dormice debería dedicarse exclusivamente a esa tarea. Si su agente también accede a herramientas mediante MCP (model context protocol), mantenga esos servidores MCP en un VPS independiente por el mismo motivo.

¿Cuántos sandboxes caben en 4 GB y 8 GB?

Dos elementos consumen memoria: la base del propio host y el conjunto de trabajo de cada sandbox que está activo. Reserve aproximadamente 1 GB para Ubuntu, Docker y el daemon. Después, divida la memoria restante por el consumo real de uno de sus sandboxes. Un sandbox que ejecuta un script de Python y lee algunos archivos suele consumir entre 200 y 300 MiB. Uno que ejecuta un compilador o una suite de pruebas completa puede superar 1 GiB.

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
  }
]

Un VPS de 4 GB admite aproximadamente 6 sandboxes activos a la vez si cada uno usa 512 MiB, o 3 si cada uno usa 1 GiB completo. En un VPS de 8 GB, esas cifras aumentan a 14 y 7. Son límites para el trabajo simultáneo, no resultados de una prueba de rendimiento. Por tanto, supervise free -m mientras se ejecuta su propia carga.

Los sandboxes congelados están limitados por el espacio de swap y no por la RAM. Ese es el objetivo del diseño. Un sandbox congelado que ocupaba 1 GiB conserva aproximadamente esa cantidad en swap y casi nada en memoria residente. Por eso, el archivo de swap predeterminado de 16 GB del instalador puede mantener aproximadamente 16 sandboxes congelados. Después, deben pasar al estado detenido, en el que sólo consumen espacio en disco. El disco es el límite real a largo plazo: cada sandbox conserva su sistema de archivos y unas pocas docenas de agentes, cada uno con un directorio node_modules, pueden llenar un volumen pequeño mucho antes de que la memoria sea un problema.

Congelar, detener, archivar: los controles del ciclo de vida

Los valores predeterminados son congelar tras 10 minutos de inactividad, detener tras 3 días y archivar tras 7 días cuando el archivado está configurado. Si establece stopAfterSeconds en null, obtiene un agente residente: puede congelarse cuando está inactivo, pero nunca inicia en frío.

El archivado es opcional y el daemon lo indica claramente. Establezca las cuatro variables DORMICE_S3_* y el disco de un sandbox detenido se empaqueta con tar y zstd, se envía a cualquier bucket compatible con S3 y se libera localmente. Ese bucket puede ser un bucket de MinIO alojado por usted mismo en otra máquina suya. Si deja las variables sin establecer, los sandbox permanecen detenidos indefinidamente y una política que solicita archivarlos se rechaza en lugar de ignorarse silenciosamente. Las restauraciones son visibles: la siguiente adquisición responde de inmediato con un estado de restauración y un valor de progreso, y cambia a listo cuando el disco vuelve a estar disponible.

¿Debería depender ya de este proyecto?

Respuesta directa: no, si se trata de algo que no pueda reconstruir. El primer commit del repositorio está fechado el 8 de julio de 2026. A fecha de 4 de agosto de 2026, el proyecto tiene 446 estrellas, 37 forks, una licencia Apache-2.0 y ningún lanzamiento etiquetado. La propia línea de estado del README indica que nada está listo para producción.

Esta combinación define un riesgo concreto. El código puede cambiar sin aviso porque el instalador sigue main. La interfaz todavía se está estabilizando. Por eso el verbo para eliminar tiene dos nombres distintos en dos archivos del mismo repositorio. Además, un proyecto de cuatro semanas puede detenerse sin más, porque ninguna cláusula de la licencia obliga a nadie a continuar su desarrollo.

La compatibilidad con E2B permite asumir este riesgo. La aplicación se comunica con un protocolo que tiene una implementación alojada. Si Dormice deja de desarrollarse, puede cambiar dos URL y continuar trabajando. Escriba el agente contra la interfaz de E2B en lugar de la API nativa para conservar esa salida. El paquete nativo @dormice/sdk tampoco está disponible todavía en npm. Para usarlo hay que compilarlo desde el repositorio, lo que constituye una segunda razón para empezar por la ruta compatible.

Ejecútelo donde pueda permitirse perderlo. Reconstruya el host mediante un script, mantenga el token fuera de todos los avisos y commits, y extraiga de los sandboxes cualquier dato que deba conservar según su propio calendario de copias de seguridad.

FAQ

¿Está Dormice listo para producción?

No, y el propio proyecto lo indica. La línea de estado del README indica que nada de lo que contiene está listo para producción todavía. Además, al 4 de agosto de 2026, el repositorio tiene unas cuatro semanas, no contiene etiquetas de git ni releases y, por tanto, no existe un número de versión que se pueda fijar. El instalador clona la rama main, por lo que cada ejecución obtiene el commit más reciente. Registre git -C /opt/dormice rev-parse HEAD después de cada instalación y mantenga cualquier dato importante fuera de los sandboxes.

¿En qué se diferencia Dormice de proporcionar a mi agente una VM desechable?

Una VM desechable es una máquina con SSH que se crea para una sesión y se elimina después. Dormice es una API de ejecución: el programa llama a acquire y después a exec, y recibe stdout y un código de salida, sin una sesión de shell intermedia. La VM es adecuada para una persona o un agente que necesita un equipo completo durante un tiempo. Dormice es adecuado para una aplicación que ejecuta código generado muchas veces al día y no necesita preparar y eliminar una máquina completa en cada ejecución.

¿El SDK oficial de E2B funciona realmente sin cambios en el código?

Sí, con cambios de configuración. Configure apiUrl y sandboxUrl para que apunten a /e2b/api y /e2b/envd en su daemon, y pase el token de Dormice con el prefijo e2b_ como clave de API. La ejecución de comandos, las sesiones PTY, la transferencia de archivos, las URL firmadas y el proxy de puertos están cubiertos por la suite de extremo a extremo del proyecto mediante el paquete oficial. La creación de plantillas es la principal limitación: e2b template build no está implementado, por lo que una plantilla es una imagen de Docker que se crea y registra con dor template add.

¿Cuántos sandboxes caben en una VPS de 4 GB?

Aproximadamente 6 activos al mismo tiempo si cada sandbox usa 512 MiB, o 3 si cada uno usa un gibibyte completo, después de reservar aproximadamente 1 GB para el sistema operativo, Docker y el daemon. Los sandboxes congelados están limitados por la swap. Por tanto, el archivo de swap predeterminado de 16 GB del instalador puede mantener aproximadamente 16 sandboxes que hayan usado un gibibyte cada uno. Mida su propio entorno con free -m bajo carga real, porque un sandbox que ejecuta una suite de pruebas usa varias veces más memoria que uno que ejecuta un script pequeño.

¿Por qué Dormice necesita establecer vm.swappiness en 100?

Congelar un sandbox significa enviar su memoria inactiva a la swap. gVisor mantiene la memoria del sandbox como memoria compartida, y el kernel de Linux no intercambia memoria compartida con el valor predeterminado de swappiness. Por tanto, con el valor predeterminado, una congelación no recupera memoria y el sandbox sigue consumiendo toda la memoria. El proyecto midió 0 bytes recuperados con el valor predeterminado y un 99.5 por ciento con el valor 100. Compruebe el valor efectivo con sysctl vm.swappiness en lugar de leer los archivos de configuración, porque algunas imágenes de proveedores cloud incluyen un valor de 0.