Sandboxesプレビュー URL

プレビュー URL: sandbox のポートを公開する

プレビュー URL は、Lizard (lizard.build) の sandbox 内のポートにプライベートな HTTPS アドレスを割り当てます。0.0.0.0 で待ち受けるサーバーを起動し、sandbox.exposePort(3000)(Python では expose_port)を呼び出すか、lizard sandbox expose <id> 3000 を実行します。https://<sandbox-id>-3000.sandbox.<region>.onlizard.com/?lizard_token=… が返されます。sandbox のアクセストークンのないリクエストには HTTP 401 が返されます。

テスト状況: 2026-10-12 に、このページを Lizard SDK、Lizard CLI 4.0.42、sandbox ルーターのソースと照らし合わせて確認しました。このページのために新たな実地テストは行っていません。

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 3000

expose はトークン付きの URL を表示するので、ブラウザーで開いてください。スクリプト用に hostname、url、port、accessToken を取得するには --json を付けます。URL を削除するには lizard sandbox unexpose $SB 3000 を実行します。

Lizard SDK から

exposePort は、ブラウザー用の url、ホスト名だけの hostname、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)もポートを公開しますが、返すのはホスト名だけで、トークンは sandbox.accessToken(Python では sandbox.access_token)に保存されます。unexpose(port) は URL を削除します。トラフィックを送る前にサーバーを起動してください。サーバーが待ち受けを始めるまで、URL は 502 を返します。

アクセスの仕組み

  • トークンは sandbox ごとに 1 つ。 トークンはポートではなく sandbox に属します。その sandbox で公開したすべてのポートに使え、sandbox が存在する間は変わりません。アクセスを断つには、ポートの公開を解除するか、sandbox を削除してください。
  • 送り方は 3 通り。 クエリパラメーター lizard_token、X-Lizard-Access-Token ヘッダー、lizard_access cookie のいずれかです。
  • ブラウザーには cookie が渡される。 ブラウザーが ?lizard_token= 付きの URL を開くと、Lizard はそのホスト名に lizard_access cookie(HttpOnly、Secure、SameSite=None、Partitioned、30 日間)を設定し、トークンを外した同じアドレスにリダイレクトします。その後はページのスクリプト、API 呼び出し、WebSocket が cookie を送るため、トークンは履歴や Referer ヘッダーに残りません。ほかのサイトがページを iframe で埋め込んだ場合も cookie は機能します。
  • ポートごとにホスト名が 1 つ。 各ポートには専用のホスト名と専用の cookie があるため、ポートごとに完全な URL を一度開いてください。
  • サーバーにトークンは届かない。 Lizard はリクエストを転送する前に、クエリ、ヘッダー、cookie からトークンを取り除きます。リクエストの Host ヘッダーは元のまま保たれます。
  • WebSocket が使える。 アップグレードリクエストはそのまま通るため、ホットリロード付きの 開発サーバーやターミナル UI も動きます。

プレビュー URL はパスワードと同じように扱ってください。URL を知っている人は誰でも、その sandbox で公開されたすべてのポートを使えます。

URL の形式と有効期間

https://<sandbox-id>-<port>.sandbox.<region>.onlizard.com

URL は sandbox の実行中だけ機能し、sandbox が停止すると使えなくなります。ポート 49983 はプラットフォームが予約しているため公開できません。SDK または CLI から作成した sandbox の既定の有効期間は 5 分です。開いたままにしたいプレビューには、より長い timeoutMs または --timeout を渡してください。有効期間の制限 を参照してください。

エラー

ステータスメッセージ対処
401This sandbox port is private (missing or wrong access token)expose が表示した完全な URL を開くか、X-Lizard-Access-Token を送ります。
403Port 3000 is not published for sandbox "…". Published: …そのポートに対して lizard sandbox expose または exposePort を実行します。
404No running sandbox "…"sandbox が実行されていません。lizard sandbox list で確認してください。
502Sandbox is not listening on port 3000サーバーを起動し、127.0.0.1 ではなく 0.0.0.0 にバインドします。

dev サーバー

ほとんどの 開発サーバーは、指定しない限り 127.0.0.1 で待ち受けます。ホストと固定のポートを渡してください:

npm run dev -- --host 0.0.0.0 --port 5173

Vite は Host ヘッダーも確認し、知らないホストには Blocked request. This host (…) is not allowed. を返します。vite.config.js で sandbox のホスト名を許可してください:

import { defineConfig } from 'vite';
 
export default defineConfig({
  server: { allowedHosts: ['.onlizard.com'] },
});

先頭のドットで、すべてのサブドメインが許可されます。そのうえで 5173 を公開します。

関連項目

更新日