Dev sandboxes autoalojadas: crea entornos de preview con Docker y Go
"El README de sandboxed explica el control plane Go, Docker, Traefik, SQLite, las URLs de preview, el idle stop y las fronteras de endurecimiento para producción."
"La documentación de Docker sobre límites de recursos explica que los contenedores no tienen límites de CPU ni memoria por defecto y necesitan restricciones explícitas."
"La documentación de Docker Sandboxes describe microVMs, daemons Docker aislados, proxying de red y aislamiento de credenciales como un modelo de seguridad más fuerte."
"El provider Docker de Traefik puede descubrir la configuración de enrutamiento desde los labels de Docker y enrutar servicios de contenedores mediante Host rules."
Las URLs de preview parecen una funcionalidad mínima: lanzar el puerto 3000 dentro de un contenedor, dar un enlace al usuario, listo. En la práctica, una dev sandbox autoalojada saca rápido a la luz colisiones de puertos, enrutamiento de dominios, reciclaje de contenedores, persistencia de archivos y orquestación por API. Los productos de coding con IA lo encuentran muy pronto: después de que el agente escribe el código, el usuario no quiere logs. Quiere hacer clic en el resultado.
Un solo docker run no basta aquí. Un diseño más estable separa cuatro piezas: un host Linux, Docker para contenedores, un control plane Go para el ciclo de vida, Traefik para dominios de preview y SQLite para el estado. Ese setup encaja con equipos de confianza y validación temprana de producto. Si vas a ejecutar código arbitrario de usuarios desconocidos, los contenedores son solo la primera capa. Deberías pensar en microVMs, hosts dedicados o Kubernetes.
Para muchos entornos efímeros, no para dos contenedores personales
Para un proyecto personal, dos contenedores, dos puertos y docker compose up -d suelen bastar. Una dev sandbox empieza a ganarse su lugar cuando el número de entornos crece, el ciclo de vida se acorta y un sistema externo necesita crear cada entorno de forma programática.
| Escenario | ¿Es buena opción una dev sandbox autoalojada? | Por qué |
|---|---|---|
| Una demo personal duradera | No mucho | Un script shell o Compose es más simple |
| Un preview por rama de equipo | Sí | Necesitas creación, enrutamiento, reciclaje y seguimiento de estado |
| Un AI app builder que genera apps pequeñas para usuarios | Muy buena opción | El agente debe escribir código en un directorio aislado y exponer una URL de preview de inmediato |
| Ejecutar código arbitrario de usuarios públicos desconocidos | Solo prototipo | Los contenedores Docker no son una frontera de aislamiento fuerte; añade VMs o microVMs en producción |
| Scheduling multinodo, escalado elástico, política de red compleja | Un solo host no basta | Kubernetes o una plataforma gestionada es más estable |
Muchos desarrolladores preguntarán primero por qué el agente no puede escribir un script shell. Pregunta justa. Un script resuelve «arrancar un contenedor». No resuelve «mantener 50 entornos vivos, detener los inactivos, despertarlos en la siguiente petición, conservar archivos, dar a cada entorno una URL estable y dejar que un backend SaaS lo controle todo por API». Cuando esos requisitos se apilan, el script empieza a convertirse en un control plane.
La arquitectura más pequeña: control plane Go, Docker, Traefik y SQLite
El diseño de tastyeffectco/sandboxes es deliberadamente pequeño: un programa Go llamado sandboxd envía comandos a Docker, Traefik enruta dinámicamente mediante labels de contenedor, SQLite guarda el estado y los workspaces viven en disco. Sin Kubernetes, sin servidor de base de datos aparte, sin cola de mensajes.
browser
|
v
Traefik ----> sandbox container ----> dev server :3000
^ ^
| |
sandboxd --------------+
|
+-- SQLite: estado de sandboxes, puertos, tareas
+-- workspaces/: un directorio persistente por sandbox
+-- reaper: idle stop / memory pressure stop
Vale la pena separar cuatro objetos.
El control plane no es el contenedor de la aplicación
El control plane Go solo debería manejar el ciclo de vida: crear una sandbox, detenerla, destruirla, ejecutar un comando, enviar una tarea de agente y leer o escribir archivos. Mantenlo delgado. No entierres toda la lógica de build dentro. El comportamiento más complejo puede vivir en la imagen base de la sandbox, una cola de tareas o la capa de aplicación encima.
Una URL de preview no es un puerto aleatorio
Cada sandbox puede exponer una dirección como s-<id>-3000.preview.localhost. Traefik lee los labels de Docker, descubre el contenedor y el puerto objetivo, y reenvía las peticiones mediante una Host rule. Los usuarios ven un enlace estable en vez de «tu puerto es 30017; intenta no chocar con alguien».
SQLite es el ancla de estado de un sistema pequeño
Los contenedores reinician. Los hosts reinician. Traefik puede recargar. SQLite registra IDs de sandbox, puertos, estado, tareas y ubicaciones de workspace. Cuando arranca el control plane, puede reconciliar el estado real de Docker contra esa base. SQLite está bien para un producto temprano en un solo host, siempre que aceptes la frontera y hagas backup.
Ejecutarlo en local: valida primero la API, los puertos y la resolución de dominio
No te apresures a conectar un agente. Confirma primero que el control plane puede arrancar contenedores, que Traefik puede reenviar y que la URL de preview abre. El quick start del README de sandboxes es directo:
git clone https://github.com/tastyeffectco/sandboxes.git
cd sandboxes
./install.sh
API=http://127.0.0.1:9090
curl "$API/healthz"
Tras pasar el health check, crea una sandbox que sirva en el puerto 3000:
ID=$(curl -s -XPOST "$API/sandbox" \
-H 'content-type: application/json' \
-d '{"ports":[3000]}' | sed -E 's/.*"id":"([^"]+)".*/\1/')
curl -s -XPOST "$API/sandbox/$ID/exec" \
-H 'content-type: application/json' \
-d '{"cmd":["bash","-lc","cd ~/workspace && python3 -m http.server 3000"]}'
Luego abre:
http://s-<id>-3000.preview.localhost
*.localhost se resuelve a tu máquina local en los navegadores modernos, útil para pruebas locales sin DNS. Para un dominio real, apunta *.preview.yourdomain.com al host y deja que Traefik maneje TLS. No expongas una API local como 127.0.0.1:9090 directamente a internet público. Como mínimo, activa la autenticación por token en producción y mantén el puerto del control plane detrás de un firewall o gateway privado.
Las URLs de preview son difíciles por el enrutamiento, los despertares y la persistencia
El port forwarding básico solo responde a «¿cómo accedo al contenedor mientras está corriendo?». Una dev sandbox también debe responder «¿qué pasa cuando el contenedor está dormido?», «¿dónde viven los archivos?» y «¿puede el mismo usuario volver más tarde?». Esas tres preguntas deciden si el sistema pasa de demo a beta.
Enrutamiento: usar el dominio como identidad del entorno
Un puerto es la perspectiva de la máquina. Un dominio es la perspectiva del producto. s-<id>-3000.preview.example.com contiene el ID de la sandbox y el puerto objetivo, así que la aplicación puede mostrar el enlace directamente al usuario. El provider Docker de Traefik lee los labels del contenedor y reenvía la Host rule al contenedor correcto.
Depura en este orden:
- DNS: ¿el dominio wildcard apunta al host, o usas
*.localhosten local? - Traefik: ¿el contenedor tiene los labels correctos y está en la misma red Docker?
- Puerto: ¿la app escucha de verdad en
0.0.0.0:3000, no solo en127.0.0.1? - Readiness: ¿tienes una página de espera o estrategia de retry mientras la app arranca?
- TLS: ¿el dominio real usa un certificado wildcard, y los entrypoints HTTP y HTTPS son consistentes?
Despertar: el idle stop no es borrar el entorno
Una sandbox inactiva se puede detener con docker stop, lo que libera memoria mientras mantiene el workspace en disco. La próxima vez que un usuario abra la URL de preview, una ruta catch-all de baja prioridad puede enviar la petición al control plane. El control plane arranca el contenedor, espera a que el puerto esté listo y luego deja que el navegador entre en la app real.
Ese mecanismo usa menos recursos que «dejar todo encendido para siempre» y se siente más de producto que «borrar el entorno cuando se queda quieto». El precio es la latencia de cold start, así que la página debería mostrar un estado de warming en vez de dejar al usuario mirando un 502.
Persistencia: los bind mounts son útiles, pero conoce la frontera
La documentación de Docker trata los bind mounts como comunes para compartir código fuente y artefactos de build. Una dev sandbox suele hacer lo mismo: un directorio del host por sandbox, montado en el workspace del contenedor. La ventaja: el código sobrevive al borrado del contenedor. La desventaja: las rutas del host y los permisos se vuelven parte del diseño del sistema.
Antes de una beta, fija al menos tres reglas: mantén los directorios de workspace separados de la configuración del control plane; haz que «borrar el contenedor» y «borrar el workspace» sean dos operaciones distintas; respalda workspaces y SQLite, no solo las capas del contenedor.
Básicos multi-inquilino: límites de recursos, Docker socket, auth de API y caché de imágenes
La documentación de Docker sobre límites de recursos es directa: los contenedores no tienen restricciones de recursos por defecto y pueden usar CPU y memoria según permita el scheduler del kernel del host. En un setup multi-inquilino, eso es un riesgo. El npm install, el build o el bucle infinito de un usuario puede ralentizar toda la máquina.
Empieza con esta checklist:
- Define límites de memoria, CPU y PID para cada sandbox.
- Mantén la API del control plane en localhost o una red privada por defecto; exige autenticación para cualquier entrypoint público.
- Trata los enlaces de preview como compartibles por defecto. Añade forward-auth cuando contengan contenido sensible.
- Preinstala las herramientas comunes en la imagen base para que cada sandbox no tenga que tirar todo de nuevo.
- Docker Hub tiene rate limits oficiales y reglas de fair use. En producción, inicia sesión, prepara caché de imágenes o usa un registro privado.
- Monta los workspaces de sandbox por separado, y nunca des
/var/run/docker.socka los contenedores de usuario. - Registra creación, detención, destrucción, ejecución de comandos y tareas de agente.
Un ejemplo de límites de recursos en Compose puede verse así:
services:
sandbox-app:
image: your-sandbox-base:latest
deploy:
resources:
limits:
cpus: "1.00"
memory: 1G
pids: 256
El mayor tema de seguridad es el Docker socket. Si sandboxd monta el Docker socket del host, tiene alta autoridad sobre el host. Eso puede ser aceptable cuando tú mantienes el control plane y los usuarios solo entran en los contenedores de sandbox que crea. Si los usuarios pueden afectar al contenedor del control plane u obtener el Docker socket, el riesgo salta más allá del aislamiento de contenedor ordinario.
Cuándo pasar a microVMs, Kubernetes o una plataforma gestionada
La ventaja de Docker en un solo host es el costo, la legibilidad y la rapidez de cambio. La desventaja es igual de clara: un host tiene capacidad limitada, la frontera de seguridad depende mucho del aislamiento de contenedores y la gobernanza del host, y el scheduling es más débil que un clúster.
| Disparador | Mejor dirección |
|---|---|
| Ejecutar código arbitrario de usuarios desconocidos | microVMs, VMs dedicadas, gVisor, Kata o Firecracker |
| Los agentes necesitan capacidad Docker completa sin tocar el daemon del host | Estilo Docker Sandboxes: microVM más daemon aislado |
| Scheduling multi-host, escalado elástico, política de red unificada | Kubernetes |
| El equipo no quiere mantener el control plane de bajo nivel | Plataforma gestionada de entornos de preview |
| Todavía validas la demanda del producto | Docker en un solo host más un control plane Go |
El modelo de seguridad oficial de Docker Sandboxes es un punto de referencia útil: pone al agente IA dentro de una microVM, le da a cada sandbox su propio daemon Docker, sistema de archivos y red, y mantiene el daemon Docker del host lejos de la sandbox. Cuesta más recursos, pero la frontera de aislamiento es más clara.
Así que empieza con un setup de un solo host para aprender el bucle de producto: crear un entorno, dejar que el agente escriba código, abrir la preview, reciclar sandboxes inactivas y conservar archivos. Cuando lleguen usuarios reales, escala la capa de aislamiento según el riesgo real. No al revés: no arrastres al equipo al mantenimiento de clúster antes de que exista el problema de escala.
Una checklist práctica del MVP a la beta
Puedes avanzar en este orden sin construir todo de una vez:
- Elige un host Linux limpio que solo corra servicios relacionados con la sandbox. No coloques bases de datos, CI runners ni aplicaciones de producción.
- Configura un dominio de preview wildcard como
*.preview.example.com. Valida primero en local con*.localhost. - Valida la API del control plane: create, exec, stop, destroy y healthz.
- Preinstala Node.js, Python, Git, los gestores de paquetes comunes y las CLI de agente que soportes en la imagen base de la sandbox.
- Añade límites de recursos, reciclaje de inactivos, persistencia de workspace y política de destrucción para cada sandbox.
- Activa la autenticación de API y añade control de acceso a los enlaces de preview cuando el negocio lo necesite.
- Registra eventos de auditoría. Monitorea la memoria del host, el disco, el número de contenedores, el tiempo de cold start y la tasa de 502.
- Ensaya backup y recuperación para SQLite, los directorios de workspace,
.envy los scripts de build de la imagen base.
Si tu siguiente paso es conectar los previews de código a la CI, lee GitHub Actions Self-Hosted Runner: la guía completa de despliegue en entorno privado. Si quieres hospedar la app Next.js generada a largo plazo, Escapar de Vercel: la guía completa para autoalojar Next.js con Docker está más cerca de la segunda mitad del camino. Para dominios públicos y protección del origen, continúa con el allowlisting de IP de origen de Cloudflare.
Preguntas frecuentes
¿En qué se diferencia una Dev Sandbox de Docker Compose?
Compose se acerca a «declaro un grupo de servicios y luego los arranco». Una Dev Sandbox se acerca a «el backend de producto crea, detiene, despierta y destruye entornos bajo demanda, y cada entorno obtiene una URL». Si los entornos son pocos y duraderos, Compose basta. Si son dinámicos por usuario, rama o tarea de agente, necesitas un control plane.
¿Por qué no usar Kubernetes?
Si ya tienes clúster, ingress, registro de imágenes, permisos y monitoreo, Kubernetes es una base sólida para entornos estandarizados. El problema es que muchos equipos tempranos solo quieren validar un AI app builder o un entorno de preview interno, y mantener el clúster puede volverse más pesado que el producto. Docker en un solo host no reemplaza a Kubernetes; mantiene ligera la primera etapa.
¿El aislamiento de contenedores puede ejecutar código de usuarios desconocidos?
No lo haría directamente. Los contenedores encajan con equipos de confianza, usuarios internos o demos de bajo riesgo. El código arbitrario de usuarios desconocidos debería correr en un aislamiento más fuerte: microVMs, VMs dedicadas, gVisor, Kata, Firecracker, o al menos hosts separados por inquilino.
¿Toda URL de preview necesita HTTPS?
Los previews locales *.localhost pueden empezar con HTTP. Para un dominio público real, usa HTTPS, sobre todo cuando los usuarios introducen tokens, formularios o datos de negocio. Un certificado wildcard reduce la molestia de emitir un certificado distinto para cada sandbox.
¿Se pierden los archivos tras un idle stop?
Mientras el workspace sea un directorio persistente, docker stop no borra archivos. La parte delicada es la diferencia entre destroy y purge: una elimina solo el contenedor, la otra también el workspace. Deja clara esa distinción en la UI del producto y en los nombres de la API.
¿Los rate limits de Docker Hub pueden afectar a este sistema?
Sí. Cuando muchos entornos arrancan, buildean y tiran imágenes con frecuencia, el registro público puede volverse una dependencia inestable. En producción, inicia sesión en Docker Hub, prepara un registro privado o caché de imágenes, e integra las dependencias comunes en la imagen base.
Conclusión
Una dev sandbox autoalojada vale la pena, pero no es solo un docker run avanzado. Es una pequeña plataforma: el control plane posee el ciclo de vida, el reverse proxy posee las URLs, el state store posee la recuperación, y los límites de recursos más la política de seguridad evitan que un entorno tumbe el host.
El camino estable es construir primero el bucle de producto con Docker en un solo host y luego escalar según el riesgo real. Cuando los usuarios son pocos, el código es de confianza y el equipo acepta una frontera de un solo host, Go + Docker + Traefik + SQLite basta. Cuando entran usuarios desconocidos, aislamiento más fuerte, scheduling multi-host o gobernanza de cumplimiento, pon microVMs, Kubernetes o una plataforma gestionada sobre la mesa.
Referencias
- tastyeffectco/sandboxes
- Docker Resource constraints
- Docker Engine security
- Docker Hub usage and limits
- Docker Sandboxes security model
- Traefik Docker provider
Construir un MVP de dev sandbox autoalojada
Un camino práctico desde la validación con Docker en un solo host hasta los controles de seguridad antes de la beta.
⏱️ Estimated time: 4 hr
- 1
Step1: Preparar un host limpio
Usa un host Linux dedicado a servicios de sandbox. No coloques en él bases de datos de producción, CI runners u otros servicios de alto valor. - 2
Step2: Configurar el dominio de preview
Valida primero en local con `*.localhost`. Para un despliegue real, apunta `*.preview.example.com` al host y configura TLS. - 3
Step3: Validar la API del control plane
Prueba como mínimo create, exec, stop, destroy y healthz para que el backend de tu aplicación pueda gestionar entornos vía API. - 4
Step4: Preparar la imagen base de la sandbox
Preinstala Node.js, Python, Git, los gestores de paquetes comunes y las CLI de agente que vayas a soportar. Eso reduce la configuración repetida tras cada arranque de sandbox. - 5
Step5: Añadir límites de recursos y reciclaje
Define límites de CPU, memoria y PID para cada sandbox. Añade idle stop, wake-on-request y manejo de workspaces persistentes. - 6
Step6: Bloquear el control plane y los previews
Activa tokens de API, red privada o reglas de firewall. Para previews sensibles, añade forward-auth o la capa de login de tu producto. - 7
Step7: Añadir logs y monitoreo
Registra create, stop, destroy, la ejecución de comandos y las tareas de agente. Monitorea la memoria del host, el disco, el número de contenedores, el tiempo de cold start y la tasa de 502. - 8
Step8: Ensayar backup y recuperación
Haz backup de SQLite, los directorios de workspace, `.env` y los scripts de build de la imagen base. Confirma que puedes restaurarlos en un host nuevo.
FAQ
¿En qué se diferencia una Dev Sandbox de Docker Compose?
¿Por qué no usar simplemente Kubernetes?
¿El aislamiento de contenedores Docker puede ejecutar código de usuarios desconocidos directamente?
¿Toda URL de preview necesita HTTPS?
¿Se pierden los archivos tras detener una sandbox inactiva?
¿Los rate limits de Docker Hub pueden afectar a un sistema de Dev Sandbox?
14 min de lectura · Publicado el: 5 jun 2026 · Actualizado el: 15 jun 2026
Comentarios
Inicia sesión con GitHub para dejar un comentario