Cloudflare Tunnels
The devx tunnel commands give you ngrok-like port exposure backed by Cloudflare's global edge network. Expose any local port to the internet with a public HTTPS URL — no port forwarding, no firewall rules, no SSL certificates to manage.
Commands
devx tunnel expose
Expose a local port to the internet:
devx tunnel expose 3000 --name myapp
# → https://myapp.your-name.ipv1337.devThis creates a DNS CNAME record in Cloudflare and adds an ingress rule to the tunnel config — all without restarting the tunnel.
Flags:
| Flag | Description |
|---|---|
--name | Subdomain name (e.g., myapp → myapp.your-name.ipv1337.dev) |
--protocol | Protocol to use (http, https, tcp) |
devx tunnel unexpose
Clean up all exposed ports:
devx tunnel unexposeThis removes the DNS records and ingress rules created by expose.
devx tunnel list
Show currently exposed ports and their public URLs:
devx tunnel listPORT NAME URL
3000 myapp https://myapp.james.ipv1337.dev
8080 api https://api.james.ipv1337.devdevx tunnel inspect
Launch a live TUI to inspect and replay HTTP traffic flowing through the tunnel:
devx tunnel inspectThis provides a real-time view of requests, responses, and headers — useful for debugging webhooks and API integrations.
devx tunnel update
Rotate Cloudflare credentials without rebuilding the VM:
devx tunnel updateHow It Works
devx vm initcreates a persistent Cloudflare Tunnel with credentials stored inside the VM- The tunnel runs as a
systemdunit (cloudflared.service) and starts automatically on boot devx tunnel exposedynamically adds ingress rules and creates DNS CNAMEs via the Cloudflare API- Traffic flows: Internet → Cloudflare Edge → Encrypted Tunnel → VM → Your Container
Use Cases
Webhook Development
Test Stripe, GitHub, or Slack webhooks against your local server:
devx tunnel expose 3000 --name webhooks
# Configure Stripe webhook URL: https://webhooks.james.ipv1337.dev/stripe/eventsSharing Work in Progress
Share a prototype with a teammate or stakeholder:
devx tunnel expose 5173 --name demo
# Send them: https://demo.james.ipv1337.devMobile Testing
Test your web app on a phone without being on the same network:
devx tunnel expose 3000 --name mobile-test
# Open https://mobile-test.james.ipv1337.dev on your phoneOAuth Callbacks & Stripe Webhooks (No Local TLS Needed)
Many third-party services — Stripe, GitHub OAuth, Google OAuth, Slack — require a verified HTTPS callback URL and reject http://localhost outright.
devx tunnel expose solves this completely. Your public tunnel URL is backed by Cloudflare's edge with a CA-signed TLS certificate. No mkcert, no local CA, no certificate management required.
devx tunnel expose 3000 --name myapp
# Configure in Stripe Dashboard:
# Webhook URL: https://myapp.james.ipv1337.dev/webhooks/stripe
# Configure in Google OAuth:
# Authorized redirect URI: https://myapp.james.ipv1337.dev/auth/callback
# Configure in GitHub OAuth App:
# Callback URL: https://myapp.james.ipv1337.dev/auth/github/callbackNo mkcert needed
Cloudflare manages TLS at the edge. Your local app still runs on plain http://localhost — the HTTPS is handled for you end-to-end.
Declarative Mode
Define port exposures in devx.yaml alongside your databases:
tunnels:
- port: 3000
name: frontend
- port: 8080
name: apiThen bring everything up:
devx up