URLs de vista previa: abrir un puerto de un sandbox
Una URL de vista previa da una dirección HTTPS privada a un puerto dentro de un sandbox de Lizard (lizard.build). Inicia un servidor que escuche en 0.0.0.0 y luego llama a sandbox.exposePort(3000) (Python: expose_port) o ejecuta lizard sandbox expose <id> 3000. Obtienes https://<sandbox-id>-3000.sandbox.<region>.onlizard.com/?lizard_token=…; una solicitud sin el token de acceso del sandbox recibe HTTP 401.
Estado de las pruebas: comprobamos esta página el 2026-10-12 con el código fuente de Lizard SDK, Lizard CLI 4.0.42 y el router de sandboxes. No hicimos una prueba en vivo nueva para ella.
Desde la CLI
lizard sandbox exec $SB -- sh -c "nohup python3 -m http.server 3000 --bind 0.0.0.0 >/tmp/http.log 2>&1 &"
lizard sandbox expose $SB 3000expose muestra la URL con el token incluido; ábrela en un navegador. Añade --json para obtener hostname, url, port y accessToken en un script. Quita la URL con lizard sandbox unexpose $SB 3000.
Desde Lizard SDK
exposePort devuelve la url para el navegador, el hostname solo y el accessToken:
import { Sandbox } from '@lizard-build/sdk';
const sandbox = await Sandbox.create('base', { projectId: 'proj_123', timeoutMs: 600_000 });
await sandbox.process.exec(
"nohup python3 -m http.server 3000 --bind 0.0.0.0 --directory /tmp >/tmp/http.log 2>&1 </dev/null &",
);
const { url, hostname, accessToken } = await sandbox.exposePort(3000);
console.log(url); // open in a browser
const res = await fetch(`https://${hostname}/`, {
headers: { 'X-Lizard-Access-Token': accessToken },
});
console.log(res.status);import httpx
from lizard import Sandbox
sandbox = Sandbox.create("base", project_id="proj_123", timeout_ms=600_000)
sandbox.process.exec_(
"nohup python3 -m http.server 3000 --bind 0.0.0.0 --directory /tmp >/tmp/http.log 2>&1 </dev/null &"
)
exposed = sandbox.expose_port(3000)
print(exposed.url) # open in a browser
res = httpx.get(f"https://{exposed.hostname}/", headers={"X-Lizard-Access-Token": exposed.access_token})
print(res.status_code)getHost(port) (Python: get_host) también publica el puerto, pero solo devuelve el hostname y guarda el token en sandbox.accessToken (Python: sandbox.access_token). unexpose(port) quita la URL. Inicia el servidor antes de enviar tráfico: hasta que escuche, la URL responde 502.
Cómo funciona el acceso
- Un token por sandbox. El token pertenece al sandbox, no a un puerto: abre todos los puertos que expongas en ese sandbox y no cambia mientras el sandbox exista. Para cortar el acceso, deja de exponer el puerto o elimina el sandbox.
- Tres formas de enviarlo. El parámetro de consulta
lizard_token, la cabeceraX-Lizard-Access-Tokeno la cookielizard_access. - Los navegadores reciben una cookie. Cuando un navegador abre una URL con
?lizard_token=, Lizard fija la cookielizard_accesspara ese hostname (HttpOnly, Secure, SameSite=None, Partitioned, 30 días) y redirige a la misma dirección sin el token. Desde ese momento, los scripts de la página, las llamadas a la API y los WebSockets llevan la cookie, y el token no queda en el historial ni en las cabeceras Referer. La cookie también funciona cuando otro sitio inserta la página en un iframe. - Un hostname por puerto. Cada puerto tiene su propio hostname y su propia cookie, así que abre una vez la URL completa de cada puerto.
- Tu servidor nunca ve el token. Lizard lo quita de la consulta, la cabecera y la cookie antes de reenviar la solicitud. La solicitud conserva su cabecera
Hostoriginal. - Los WebSockets funcionan. Las solicitudes de upgrade pasan, así que funcionan los servidores de desarrollo con recarga en caliente y las interfaces de terminal.
Trata una URL de vista previa como una contraseña: quien la tenga puede usar todos los puertos expuestos de ese sandbox.
Formato de la URL y duración
https://<sandbox-id>-<port>.sandbox.<region>.onlizard.comLa URL funciona mientras el sandbox está en marcha y deja de funcionar cuando se detiene. La plataforma reserva el puerto 49983; no puedes exponerlo. Un sandbox creado desde el SDK o la CLI dura cinco minutos por defecto; pasa un timeoutMs o un --timeout más largo para una vista previa que quieras mantener abierta. Consulta los límites de duración.
Errores
| Estado | Mensaje | Solución |
|---|---|---|
| 401 | This sandbox port is private (missing or wrong access token) | Abre la URL completa que muestra expose o envía X-Lizard-Access-Token. |
| 403 | Port 3000 is not published for sandbox "…". Published: … | Ejecuta lizard sandbox expose o exposePort para ese puerto. |
| 404 | No running sandbox "…" | El sandbox no está en marcha. Revisa lizard sandbox list. |
| 502 | Sandbox is not listening on port 3000 | Inicia el servidor y haz que escuche en 0.0.0.0, no en 127.0.0.1. |
Servidores de desarrollo
La mayoría de los servidores de desarrollo escuchan en 127.0.0.1 salvo que les indiques otra cosa. Pasa el host y un puerto fijo:
npm run dev -- --host 0.0.0.0 --port 5173Vite además comprueba la cabecera Host y responde Blocked request. This host (…) is not allowed. a los hosts que no conoce. Permite los hostnames del sandbox en vite.config.js:
import { defineConfig } from 'vite';
export default defineConfig({
server: { allowedHosts: ['.onlizard.com'] },
});Un punto al principio permite todos los subdominios. Después, expón 5173.
Ver también
- Ejecutar Claude Code en un sandbox
- Ejecutar OpenCode en un sandbox, incluida su interfaz web
- Inicio rápido de Sandboxes
- Referencia del SDK
lizard sandbox
Actualizado