INTEGRITY Dokumentace

Preview URLs

Rychlé nasazení

Pro rychlá preview nasazení doporučujeme používat Cloudflare Tunnel ↗ pro generování náhledových URL adres pro vaše webové služby. Fungují jak při lokálním vývoji, tak na workers.dev i v produkčním provozu.

await sandbox.startProcess("python -m http.server 8000");
const tunnel = await sandbox.tunnels.get(8000);
console.log(tunnel.url);
// https://acute-llama-dancing-roundly.trycloudflare.app

// Request will be routed directly to the webserver running on the sandbox.
const req = await fetch(`${tunnel.url}/api/users`); // => GET http://localhost:8000/api/users

Podpora Cloudflare Tunnel má v současnosti následující omezení:

Viz referenční dokumentace k Tunnels API pro úplné API a sadu funkcí.

Produkční provoz, stabilní URL adresy a vlastní domény

Pro produkční použití doporučujeme používat exposePort() API a směrování provozu přes váš Worker.

URL adresy náhledu poskytují veřejný přístup přes HTTPS ke službám běžícím uvnitř sandboxů. Při zveřejnění portu získáte jedinečnou URL adresu, která přesměrovává požadavky na vaši službu.

// Extract hostname from request
const { hostname } = new URL(request.url);

await sandbox.startProcess("python -m http.server 8000");
const exposed = await sandbox.exposePort(8000, { hostname });

console.log(exposed.url);
// Production: https://8000-sandbox-id-abc123random4567.yourdomain.com
// Local dev: http://8000-sandbox-id-abc123random4567.localhost:{port}/

Formát URL

Produkce: https://{port}-{sandbox-id}-{token}.yourdomain.com

Lokální vývoj: http://{port}-{sandbox-id}-{token}.localhost:{dev-server-port}

Typy tokenů

Automaticky vygenerované tokeny (výchozí)

Pokud není zadán vlastní token, vygeneruje se náhodný 16znakový token:

const exposed = await sandbox.exposePort(8000, { hostname });
// https://8000-sandbox-id-abc123random4567.yourdomain.com

Adresy URL s automaticky generovanými tokeny se změní, jakmile port skryjete a znovu zpřístupníte.

Vlastní tokeny pro stabilní URL adresy

Pro produkční nasazení nebo sdílené URL zadejte vlastní token, aby zůstala zachována konzistence i po restartu kontejneru:

const stable = await sandbox.exposePort(8000, {
	hostname,
	token: "api_v1",
});
// https://8000-sandbox-id-api_v1.yourdomain.com
// Same URL every time ✓

Požadavky na token:

Případy použití vlastních tokenů:

Rozlišování velkých a malých písmen v ID

URL adresy náhledu extrahují ID sandboxu z názvu hostitele, aby mohly směrovat požadavky. Vzhledem k tomu, že názvy hostitelů nerozlišují velikost písmen (podle RFC 3986), vždy se převádí na malá písmena: 8080-MyProject-123.yourdomain.com se změní na 8080-myproject-123.yourdomain.com.

Problém: Pokud vytvoříte sandbox s "MyProject-123", existuje jako Durable Object s přesně tímto ID. Náhledová URL však směruje na "myproject-123" (převedeno na malá písmena z hostname). Jde o odlišné instance Durable Object, takže sandbox není přes preview URL dostupný.

// Problem scenario
const sandbox = getSandbox(env.Sandbox, "MyProject-123");
// Durable Object ID: "MyProject-123"
await sandbox.exposePort(8080, { hostname });
// Preview URL: 8080-myproject-123-token123.yourdomain.com
// Routes to: "myproject-123" (different DO - doesn't exist!)

Řešení: Použijte normalizeId: true k převodu ID na malá písmena při vytváření sandboxů:

const sandbox = getSandbox(env.Sandbox, "MyProject-123", {
	normalizeId: true,
});
// Durable Object ID: "myproject-123" (lowercased)
// Preview URL: 8080-myproject-123-token123.yourdomain.com
// Routes to: "myproject-123" (same DO - works!)

Bez normalizeId: true, exposePort() vyvolá chybu, pokud ID obsahuje velká písmena.

Doporučený postup: Od začátku používejte ID malými písmeny ('my-project-123'). Viz Možnosti sandboxu - normalizeId s podrobnostmi.

Směrování požadavků

Musíte zavolat proxyToSandbox() jako první ve fetch handleru vašeho Workeru, aby se směrovaly požadavky na preview URL:

import { proxyToSandbox, getSandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
	async fetch(request, env) {
		// Handle preview URL routing first
		const proxyResponse = await proxyToSandbox(request, env);
		if (proxyResponse) return proxyResponse;

		// Your application routes
		// ...
	},
};

Tok požadavků: prohlížeč → váš Worker → Durable Object (sandbox) → vaše služba.

Více portů

Zpřístupněte více služeb současně:

// Extract hostname from request
const { hostname } = new URL(request.url);

await sandbox.startProcess("node api.js"); // Port 3000
await sandbox.startProcess("node admin.js"); // Port 3001

const api = await sandbox.exposePort(3000, { hostname, name: "api" });
const admin = await sandbox.exposePort(3001, { hostname, name: "admin" });

// Each gets its own URL with unique tokens:
// https://3000-abc123-random16chars01.yourdomain.com
// https://3001-abc123-random16chars02.yourdomain.com

Co funguje

Co nefunguje

Podpora WebSocket

URL adresy náhledu podporují připojení WebSocket. Když požadavek na upgrade WebSocket dorazí na zveřejněný port, směrovací vrstva automaticky zajistí navázání spojení.

// Extract hostname from request
const { hostname } = new URL(request.url);

// Start a WebSocket server
await sandbox.startProcess("bun run ws-server.ts 8080");
const { url } = await sandbox.exposePort(8080, { hostname });

// Clients connect using WebSocket protocol
// Browser: new WebSocket('wss://8080-abc123-token123.yourdomain.com')

// Your Worker routes automatically
export default {
	async fetch(request, env) {
		const proxyResponse = await proxyToSandbox(request, env);
		if (proxyResponse) return proxyResponse;
	},
};

Pro vlastní scénáře směrování, kdy váš Worker musí podle vlastností požadavku určit, ke kterému sandboxu nebo portu se připojit, viz wsConnect() v Ports API.

Security

Vestavěné zabezpečení:

Přidejte autentizaci na úrovni aplikace:

Pro vyšší zabezpečení implementujte ověřování přímo ve své aplikaci:

from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/data')
def get_data():
    # Check for your own authentication token
    auth_token = request.headers.get('Authorization')
    if auth_token != 'Bearer your-secret-token':
        abort(401)
    return {'data': 'protected'}

Tím se přidává druhá vrstva zabezpečení nad rámec URL tokenu.

Řešení potíží

URL není dostupná

Zkontrolujte, zda služba běží a naslouchá:

// 1. Is service running?
const processes = await sandbox.listProcesses();

// 2. Is port exposed?
const ports = await sandbox.getExposedPorts();

// 3. Is service binding to 0.0.0.0 (not 127.0.0.1)?
// Good:
app.run((host = "0.0.0.0"), (port = 3000));

// Bad (localhost only):
app.run((host = "127.0.0.1"), (port = 3000));

Chyby v produkci

Při potížích s vlastní doménou se podívejte na řešení potíží s vlastní doménou pro náhledové URL adresy.

Lokální vývoj