Cloudflare Tunnel
This guide walks you through setting up a Cloudflare Tunnel to connect your private services to the internet without a publicly routable IP address.
-
Create a Tunnel
Add a Tunnel resource to your
alchemy.run.ts
file:import alchemy from "alchemy";import { Tunnel } from "alchemy/cloudflare";const app = await alchemy("my-app");// Create a tunnel with ingress rulesconst tunnel = await Tunnel("web-app", {name: "web-app-tunnel",ingress: [{hostname: "app.example.com",service: "http://localhost:3000",},{service: "http_status:404", // catch-all rule (required)},],});// Display the tunnel tokenconsole.log("Tunnel created!");console.log("Token:", tunnel.token.unencrypted);await app.finalize(); -
Deploy the Tunnel configuration
Deploy your tunnel configuration to Cloudflare:
Terminal window bun alchemy deployTerminal window npx alchemy deployTerminal window pnpm alchemy deployTerminal window yarn alchemy deploySave the token that’s displayed - you’ll need it to run cloudflared.
-
Install cloudflared
Install the cloudflared connector on your origin server:
Terminal window brew install cloudflaredTerminal window winget install --id Cloudflare.cloudflaredDownload the latest release from the official releases page.
Terminal window docker pull cloudflare/cloudflared:latestFor detailed installation instructions for your platform, see the official Cloudflare documentation.
-
Run the Tunnel
Start cloudflared with the token from step 2:
Terminal window # Run as a service (recommended)sudo cloudflared service install <TUNNEL_TOKEN># Or run in foreground for testingcloudflared tunnel run --token <TUNNEL_TOKEN>Terminal window # Run as a service (as administrator)cloudflared.exe service install <TUNNEL_TOKEN># Or run in foreground for testingcloudflared.exe tunnel run --token <TUNNEL_TOKEN>Terminal window docker run -d \--name cloudflared-tunnel \--restart unless-stopped \cloudflare/cloudflared:latest \tunnel --no-autoupdate run --token <TUNNEL_TOKEN> -
Start your local service
Make sure your application is running on the port specified in the ingress rules:
Terminal window # Example: Start a simple HTTP server on port 3000npx http-server -p 3000# Or run your application# node app.js# python -m http.server 3000# etc. -
Test your tunnel
Visit your configured hostname to verify the tunnel is working:
Terminal window curl https://app.example.comYou should see the response from your local service!
Next Steps
Section titled “Next Steps”Now that you have a basic tunnel running, explore these advanced features:
- Multiple services - Route different hostnames and paths to different services
- Private network access - Enable WARP routing for secure connectivity
- Origin configuration - Customize timeouts, TLS settings, and more
- Access policies - Add authentication and authorization to your tunnel
See the Tunnel Provider Reference for complete documentation on all available options.
Learn More
Section titled “Learn More”- Tunnel Provider Reference - Complete API documentation
- Cloudflare Tunnel Documentation - Official Cloudflare docs
- Zero Trust Access Policies - Secure your tunnel with access controls