Pre-baked Cloudflared and Default Tunnel Ingress¶
Previously, sandboxes relied solely on ephemeral Modal tunnels (sandbox.tunnels()[web_port].url) or direct SSH connections to access web applications running inside the container. We decided to pre-bake the standalone cloudflared binary into the Shared Base Image and start Cloudflare Tunnel as a background service by default during sandbox bootstrap. The service automatically routes external HTTPS traffic from the persistent custom domain https://3000.mahesh0.dev directly to local port 3000 across all Standard and VM Sandboxes without requiring open inbound firewall ports.
Considered Options¶
- Runtime installation in
startup.shon every launch: Download and installcloudflareddynamically during sandbox boot. Rejected because downloading binaries at startup introduces latency and external network failure modes to every sandbox boot. - Opt-in CLI flag
--cloudflare: Require an explicit--cloudflareflag to install or run the tunnel. Rejected because developer preview workflow requires the persistent custom domain3000.mahesh0.devout of the box by default for zero-config iteration. - Pre-baked binary with port-aware watcher daemon and
--no-cloudflareescape hatch: Pre-bake/usr/local/bin/cloudflaredinto the Shared Base Image inshared/image.py. Inshared/startup.sh, configure the service and supervise it via a background port watcher daemon (cloudflared-port-watcher). The watcher monitors/dev/tcp/127.0.0.1/$PORT, startingcloudflaredonly when an application binds to the port and stopping it immediately when the port closes. Add a--no-cloudflareopt-out flag tostandard_sandbox/main.pyandvm_sandbox/main.pyto prevent connector registration entirely when desired. Accepted because it delivers instant boot times, 100% Modal layer cache reuse, zero-config default availability, and completely eliminates 502/connection-refused collisions from idle sandboxes.
Consequences¶
shared/image.pypre-bakes/usr/local/bin/cloudflaredinbase_image, shared by both Standard and VM Sandboxes.shared/startup.shconfigures Cloudflare Tunnel early during Step 0 viacloudflared service install, guarded byENABLE_CLOUDFLARE != 0and protected with idempotency checks against duplicate service creation.- A background daemon
cloudflared-port-watchercontinuously polls the local port (default: 3000): startingcloudflareddynamically when the local dev server starts and stopping it when the dev server stops, ensuring idle sandboxes do not hijack traffic. - A fallback tunnel token is configured in
shared/startup.sh, while allowing overrides via theCLOUDFLARE_TUNNEL_TOKENenvironment variable. - An inspection utility
check-cloudflare(aliased tocheck-cf) is created in/usr/local/bin/inside the sandbox to inspect version, service status, running processes, port watcher status, and token configuration. standard_sandbox/main.pyandvm_sandbox/main.pyprovide--no-cloudflareto disable tunnel startup and connector registration.print_access_infoannounces• Cloudflare: https://3000.mahesh0.dev (port 3000)upon sandbox readiness.
Amendments¶
- Non-Intrusive Socket Monitoring: The port watcher daemon in
shared/startup.shwas amended from raw TCP socket writing (echo > /dev/tcp/127.0.0.1/$PORT) to inspecting/proc/net/tcpfor listening sockets (0A). This eliminates spuriousInvalid HTTP request receivedwarnings in HTTP servers like Uvicorn caused by raw newline probes while preserving dynamic tunnel startup and shutdown. - Zombie Process Rejection in Init Script: In container environments where PID 1 does not reap re-parented child processes, terminated cloudflared daemons linger as defunct zombies. Because
ps <pid>succeeds on zombie processes in/proc,/etc/init.d/cloudflaredfalsely treated dead processes as active, failing to delete/var/run/cloudflared.pidand preventingcloudflared-port-watcherfrom starting the daemon when target ports activate.shared/startup.shwas amended to patch/etc/init.d/cloudflaredto verify that the PID is alive and not in a zombie state (State: Zin/proc/$PID/status), and to cleanly unlink stale PID files.