Getting started with Cloudflare Tunnel
Occasionally we need to expose our local development projects to the internet. Whether it's for testing webhooks, sharing our work with clients, or collaborating with remote team members, having a secure and reliable way to make our local projects accessible is crucial. For years, ngrok and Expose has been my go-to tools, but I recently discovered a powerful alternative: Cloudflare Tunnel.
Why I Switched to Cloudflare Tunnel
I've used ngrok for tunneling for a long time. But when I recently was working on a Shopify project, I discovered Cloudflare Tunnel. Shopify extensions uses this by default for connecting you local development environment to your development test store. After looking into it more, I found some good reasons to use Cloudflare Tunnel:
- It's Completely Free: Unlike ngrok, which requires a paid plan for many features, like serving multiple projects at the same time, Cloudflare Tunnel is free to use, even for advanced features.
- Static URLs: With a domain configured on Cloudflare, I can set up static URLs for my projects. This makes sharing and remembering project URLs so much easier.
- Built-in Security: Cloudflare Tunnel uses outbound-only connections, which means I don't need to open any ports in my firewall. This gives me peace of mind when exposing local services.
Free to Use, Even for Advanced Features
One of the biggest draws of Cloudflare Tunnel is that it's free to use. This isn't just a basic free tier with limited functionality - you get access to all features without any cost. Here's what this means for developers:
- No usage limits: You can create as many tunnels as you need without worrying about hitting a cap.
- All features included: Unlike ngrok, where features like custom subdomains are locked behind a paywall, Cloudflare Tunnel gives you everything out of the box.
This makes Cloudflare Tunnel an excellent option for developers.
Static URLs Make Sharing Easier
Setting up static URLs is really useful, especially when you're often sharing your work with clients or team members. Here's why it's great:
- Same URL every time: Once you set up a static URL, it stays the same whenever you start your tunnel. You don't need to send new URLs and ports each time you restart your project.
- Looks better: Custom subdomains (like
https://preview.einarhansen.dev
) look nicer and are easier to remember than random strings from other tunneling services. - Easier setup: For things like webhooks that need a fixed URL, you only need to set it up once.
- Works well with Shopify: In my case, I don't need to change the dev store URL in the Shopify Partners dashboard every time the tunnel restarts or gets a new port.
This feature has saved me a lot of time and made working with others much smoother.
Built-in Security with Outbound-Only Connections
Security is paramount when exposing local services to the internet, and this is where Cloudflare Tunnel really shines. The outbound-only connection model provides several security benefits:
- No open inbound ports: Traditional methods often require you to open ports in your firewall, which can be a security risk. Cloudflare Tunnel eliminates this need entirely.
- Encrypted connections: All traffic between your local environment and Cloudflare's edge network is encrypted using TLS.
- Reduced attack surface: By not exposing your origin server directly to the internet, you significantly reduce the potential attack vectors.
This security model gives me peace of mind when I need to expose internal services temporarily to the internet.
Setting Up Cloudflare Tunnel: A Step-by-Step Guide
Let's walk through the complete process of setting up Cloudflare Tunnel for your local development environment. This guide assumes you're using macOS, but the steps are similar for other operating systems.
Step 1: Sign Up for a Cloudflare Account
If you don't already have one, start by signing up for a free Cloudflare account at https://dash.cloudflare.com/sign-up.
Step 2: Transfer Your Domain to Cloudflare
To use Cloudflare Tunnel with a custom domain, you'll need to transfer your domain's DNS management to Cloudflare:
- Log in to your Cloudflare account.
- Click "Add a Site" and enter your domain name.
- Select the free plan.
- Follow the instructions to update your domain's nameservers with your domain registrar.
This process can take up to 24 hours to complete, but from my experience it takes about 15 minutes.
Step 3: Install cloudflared
Now, let's install the cloudflared
daemon. On macOS, you can use Homebrew. For other operating systems, check the official Cloudflare documentation.
brew install cloudflared
Step 4: Authenticate cloudflared
Run the following command to authenticate cloudflared
with your Cloudflare account:
cloudflared tunnel login
This will open a browser window where you can log in to your Cloudflare account and authorize the tunnel.
Step 5: Create a Tunnel
Now, let's create a named tunnel, in this case for einarhansen.dev:
cloudflared tunnel create <project-name>
# example:
cloudflared tunnel create einarhansen.dev
This command will create a tunnel and generate a credentials file.
Step 6: Create a DNS Route
Create a DNS route for your tunnel using the CLI:
cloudflared tunnel route dns <project-name> <hostname>
# example:
cloudflared tunnel route dns einarhansen.dev preview.einarhansen.dev
This command creates a CNAME record in your Cloudflare DNS settings, pointing your chosen subdomain to your tunnel.
Step 7: Configure Your Tunnel
Next, you need to find the tunnel ID and the credentials file for your project. Here's how:
- List your tunnels by running:
cloudflared tunnel list
Copy the UUID from the ID
column for your tunnel.
- Find the credentials file by listing the contents of the Cloudflare directory:
ls -la ~/.cloudflared
Look for a file named <tunnel-id>.json
. This is your credentials file.
Step 8: Create Your Configuration File
Now it's time to create the configuration file for your tunnel. Follow these steps:
-
Navigate to your
~/.cloudflared
directory (remember to show hidden files if you are using Finder). -
Create a new file named
config.yml
using any text editor you prefer. This file will configure the tunnel to route traffic from a given origin to the hostname of your choice. -
Add the following content to your
config.yml
file:
tunnel: <YOUR-TUNNEL-ID>
credentials-file: /path/to/your/credentials-file.json
ingress:
- hostname: <hostname>
service: http://localhost:8000
- service: http_status:404
-
Replace
<YOUR-TUNNEL-ID>
with the UUID you copied in Step 7. -
Update the
credentials-file
path to match the location of your.json
credentials file (also from Step 7). Use the full path, e.g.,/Users/einar/.cloudflared/<tunnel-id>.json
. -
Adjust the
hostname
to match your desired subdomain and domain. It should match the CNAME record you created in Step 6. In my case, it'spreview.einarhansen.dev
. -
Modify the
service
URL to match the local address and port where your application is running.
Here's an example of a config.yml
file if we are running a Next.js project on port 3000 and a static site on port 8880. Remember to run Step 6 to create a DNS record for all the domains you add in the config:
tunnel: <YOUR-TUNNEL-ID>
credentials-file: /path/to/your/credentials-file.json
tunnel: de43418a-5173-476c-9a8f-2f68b567f2ed
credentials-file: /Users/einar/.cloudflared/de43418a-5173-476c-9a8f-2f68b567f2ed.json
ingress:
- hostname: <hostname>
service: http://localhost:8000
- hostname: preview.einarhansen.dev
service: http://localhost:8080
- hostname: nextjs.einarhansen.dev
service: http://localhost:3000
- service: http_status:404
This configuration allows you to route traffic to multiple local services using different subdomains.
Step 9: Start Your Tunnel
With your configuration file in place, you can now start your tunnel. Run the following command:
cloudflared tunnel --config ~/.cloudflared/config.yml run
And there you have it! Your local project is now accessible at https://preview.einarhansen.dev
. You can share this URL with anyone, and they'll be able to access your local project securely.
Wrapping Up
Cloudflare Tunnel has become an indispensable tool in my development workflow. It's free, secure, and offers the flexibility of static URLs, making it a compelling alternative to ngrok. The initial setup might seem a bit more involved compared to ngrok, but the benefits are well worth it, especially for long-term projects or when you need persistent, custom subdomains.
Give it a try in your next project, and let me know on x.com how it works for you! Remember, while Cloudflare Tunnel is powerful, always be cautious about what you expose to the internet. Ensure you're not accidentally sharing sensitive information, and don't run your app in debug mode while exposing it to the internet.
Happy tunneling!