Tienes una app de React Router que habla con un agente por ACP. Corre en tu Mac y quieres que corra en internet, con su URL, sin que tu laptop tenga que estar abierta. Este tutorial es esa mudanza, con los comandos que puedes copiar tal cual.
El resultado son dos cajas: una corre al agente, la otra corre a la app. Se hablan por WebSocket.
Lo que necesitas
- Una API key de EasyBits (panel → Ajustes → API keys).
- El agente ya corriendo en su propia caja, con su endpoint
wss://…/acpy su secreto. Ese paso está contado en Cómo correr tu agente de código en una microVM y conectarlo a VS Code. - El repo de tu app en GitHub, público o con token.
- Que tu app arranque con un comando y escuche en un puerto. Nada más.
Las variables
Todo lo demás usa estas dos. Cópialas primero y ajusta la llave:
1. Lanzar
Una llamada provisiona la máquina, clona el repo adentro, buildea, arranca y expone HTTPS:
La respuesta trae lo que vas a usar en los pasos siguientes:
Guarda el id de la máquina:
Tu Mac mandó un JSON con la URL del repo. El git clone, el npm ci y el build ocurren dentro de la caja, sobre Linux. Un node_modules compilado en macOS no sobrevive el viaje, y por eso nunca se sube.
Con tier: "micro" (1 vCPU, 1 GB) el build de esta app tardó 6 segundos y bajó 375 paquetes. El nano de 256 MB se queda sin memoria a medio build.
2. Los secretos, al vault
Si intentas pasar tus llaves en el campo env del launch, la API te frena:
El env del runspec viaja dentro de cada release, así que ahí sólo van cosas públicas. Los secretos se cargan aparte, en un objeto plano de NOMBRE: valor:
Responde con los nombres que quedaron registrados:
Los valores se guardan cifrados y se materializan sólo dentro de la máquina, al buildear y al arrancar. Puedes listar los nombres cuando quieras; los valores no se recuperan por API, ni siquiera siendo el dueño.
3. Redesplegar para que los tome
Los secretos se inyectan al arrancar, así que hay que publicar un release nuevo. El mismo endpoint, ahora con sandboxId para decir a qué máquina va:
Sube a "version": 2. Cada deploy es un release; el anterior queda disponible.
4. Verificar
Un exitCode: 0 dice que el arranque no reventó, no que el sitio conteste. Eso se comprueba con un GET:
Hasta que salga 200, la app no está publicada.
Tu propio dominio
La URL …sandboxes.easybits.cloud sirve para trabajar, no para presumir. Para colgar un dominio tuyo, pásalo en el mismo launch:
La respuesta trae domain.dns: ese es el registro exacto que hay que crear con tu proveedor. Una vez que propague, tu app responde en las dos direcciones.
Cuando algo falla
El log de la app, antes de reintentar nada:
Dos errores que vas a encontrar, con su arreglo:
node: .env: not found. El npm start de muchos proyectos es node --env-file=.env server.js. Ese archivo está en .gitignore, así que no llega a la caja. En producción las variables ya vienen del vault, así que el startCommand es node server.js a secas.
upstream unreachable / "nada escucha en el puerto 3000". Declaraste 3000 y tu server escucha en otro. En esta app el default era process.env.PORT ?? 4000. Cámbialo a 3000 en el código o declara "port": 4000 en el launch; lo que importa es que coincidan.
Si un release quedó peor que el anterior, vuelves atrás sin rebuildear:
La prueba de fuego
Abre la URL y pídele algo al agente. Si los secretos llegaron, la app despierta la otra caja, corre la herramienta y te devuelve el resultado con su costo:
La caja del agente es la del post anterior: la que levantamos con goose escuchando ACP en 0.0.0.0. Ahí quedó lista para que se conectara VS Code; hoy quien se conecta es una webapp con su propia URL.
Cada caja vive por su lado. La del agente se duerme a los 15 minutos sin actividad y despierta cuando llega el siguiente mensaje; la de la app se queda escuchando siempre, porque alguien puede abrir la URL en cualquier momento.
Este recorrido es el cierre de la segunda sesión del taller de Sistemas Agénticos, donde construimos la interfaz completa: la tarjeta que muestra qué comando corrió el agente, el envío de imágenes y este deploy. Si te interesa el tema, el taller vive aquí.
Abrazo. Blissmo. 🤓
