Skip to content

PATTERN Cited by 1 source

Ephemeral preview URL via port-forward

Shape

In a session-scoped dev environment on a platform-owned substrate, automatically detect any bound port the running application opens, and publish a publicly-reachable preview URL (on a platform-owned subdomain) that reverse-proxies to that port through the platform's routing fabric. No manual deploy step, no infrastructure changes — binding a port is the deployment signal.

Canonical instance

Phoenix.new (Fly.io, 2025-06-20) — *.phx.run URLs. From the source post:

They have private, shareable URLs (we detect anything the agent generates with a bound port and give it a preview URL underneath phx.run, with integrated port-forwarding).

The pattern rides on Fly.io's existing substrate: the session VM is a normal Fly Machine, so its ports are reachable by systems/fly-proxy; Fly.io owns the phx.run domain; the remaining piece is the port-detection layer that maps session-ID + port → <subdomain>.phx.run routing rule.

Why this matters

The target pain point is the delay between code working locally and code being reachable as a URL someone else can open. The 2025-06-20 post quotes Karpathy's restaurant-menu-visualizer story: "The code … was the easy part; he had it working in an afternoon. But getting the app online took him a whole week." Ephemeral preview URLs collapse the \"deploy to share\" step to zero.

For coding agents specifically, the value is amplified:

  • The agent's verification loop needs the URL to be reachable from its own tools. Phoenix.new's agent drives its own browser against the preview URL; the browser tool wants the URL in the same way the human observer does.
  • The human can watch. Any .phx.run tab the developer has open updates live as the agent works — the preview URL is simultaneously an agent verification surface and a human observer surface.

Adjacent patterns

  • patterns/ephemeral-preview-environments — per-PR / per-change CI-deployed previews. Similar outcome (shareable URL per unit of work) but driven by deploy pipelines rather than port-bind detection. Works well for git-driven review flows; ephemeral preview URLs via port-forward work better for interactive session-based flows.
  • Local ngrok / Cloudflare Tunnel / tailscale funnel — same "expose local port publicly" mechanic but on a laptop-run process, with a point-to-point tunnel. Ephemeral preview URLs via port-forward are the platform-native variant for sessions that already live on the platform.
  • Codespaces / Gitpod port forwarding — same class of primitive; GitHub Codespaces publishes authenticated preview URLs on <port>-<codespace>.preview.app.github.dev when you bind a port.

Required substrate capabilities

  1. The app runs on the platform. Preview-URL-via-port-forward assumes the bound port is reachable by the platform's routing fabric; it's a non-starter for laptop-run code without a tunnel.
  2. Platform owns a shareable domain. phx.run for Phoenix.new; preview.app.github.dev for Codespaces; <foo>.gitpod.io for Gitpod.
  3. Port-binding observer. Something — fly-proxy-side, sidecar inside the VM, syscall hook — notices when the app starts listening on a port, and plumbs a routing rule.
  4. Routing layer that can map session-ID + port → inner upstream. For Phoenix.new, this is <session>.phx.runfly-proxy → the session Machine's bound port.

Trade-offs

  • Pro: zero-deploy sharing; agent tools and human observers get the same URL; lives as long as the session, dies with it.
  • Con: any bound port gets published. Debug servers, internal service endpoints, developer conveniences can leak. Some platforms (Codespaces) gate sharing per-port; others publish by default. The 2025-06-20 post doesn't disclose whether Phoenix.new's URLs are token-guarded or security-by-obscurity.
  • Dependency on session lifetime. Sharing the preview URL with someone else implies they'll hit it before session teardown — if the agent goes idle and the VM is reaped, the URL dies. Different products handle this differently (sleep- and-resume vs strict-teardown).

Caveats

  • Routing mechanics (how *.phx.run maps to session Machines through systems/fly-proxy) are gestured at in the post, not sketched.
  • Security posture is under-disclosed — private-shareable isn't a crisp auth claim.
  • Multi-port apps need subdomain-per-port routing; how that maps is not specified.
  • TLS certs for *.phx.run are presumably wildcard / ACME- automated but not discussed.

Seen in

Last updated · 200 distilled / 1,178 read