Cloudflare Tunnel is a free alternative to Ngrok that allows publicly exposing your local web server. Usually, it’s used in development for testing webhooks or some third-party APIs that require public URLs. In my case, I use it for Shopify Apps development.
One of the biggest benefits of Cloudflare Tunnel is that it allows using custom domains with tunnels for free. This way you can have a permanent public URL which is much better than random URLs in Ngrok’s free plan. Another benefit is that you can store tunnel configuration inside git repository next to your app so your team members may start tunnels without any additional setup and without a Cloudflare account. Let’s take a look at how you can set things up.
Step 1: Domain
First thing first you’ll need a domain that will be used to start tunnels for development. I use separate platmart.dev
domain for that and have tunnels on subdomains: [app-name].platmart.dev
. Once you get it you’ll need to create a Cloudflare account and add you dev domain to it: Creating a Cloudflare account and adding a website
Step 2: Setup CLI
Next you’ll need to setup a CLI for Cloudflare Tunnel. It’s called cloudflared
. For macOS you can install it via homebrew (for other operating systems check installation options):
brew install cloudflare/cloudflare/cloudflared
After that run:
cloudflared tunnel login
It will open browser and prompt you to login into you Cloudflare account. Select your dev domain from Step 1. This will generate account certificate in ~/cloudflared/cert.pem
.
Step 3: Create tunnel
To create your first tunnel run:
cloudflared tunnel create <Tunnel-NAME>
This will create new tunnel and save it’s credentials in ~/.cloudflared/<Tunnel-UUID>.json
. Now create a subdomain for this tunnel:
cloudflared tunnel route dns <Tunnel-NAME> <SUBDOMAIN>
It will create CNAME record for your dev domain and point it to tunnel.
Step 4: Connect to app
Time to connect tunnel to the app. Create .cloudflared
folder inside app.
Add .cloudflared/credentials.json
and copy tunnel credentials to it from ~/.cloudflared/<Tunnel-UUID>.json
.
Create .cloudflared/config.yml
file with the following content:
tunnel: <Tunnel-UUID>
credentials-file: .cloudflared/credentials.json
noTLSVerify: true
Add bin/tunnel
file inside app with the following content:
#!/usr/bin/env bash
cloudflared tunnel --config .cloudflared/config.yml --url localhost:3000 run <Tunnel-NAME>
And set execute permissions for bin/tunnel
:
chmod +x bin/tunnel
Replace 3000 port with your app’s port if needed. Commit these changes to git repository.
Step 5: Run the tunnel
To run the tunnel inside app folder call:
bin/tunnel
This command will start the tunnel. You team mates will only need to download cloudflared
CLI tool. They won’t need to login to Cloudflare or have certificate to start a tunnel.
To view the list of all tunnels with their statuses you’ll need to create a free Cloudflare for Teams account here. Then go to “Access” > “Tunnels” page:
Bonus: Multiple tunnels per app
When working with team single tunnel won’t be enough. Not a big problem. We can create additional tunnels and use them in a similar way. Every new tunnel will have incremental suffix -N
added to it’s name:
cloudflared tunnel create <Tunnel-NAME>-2
cloudflared tunnel route dns <Tunnel-NAME>-2 <SUBDOMAIN>-2
Credentials file will have a suffix too: .cloudflared/credentials-2.json
.
And .cloudflared/config-2.yml
as well:
tunnel: <Tunnel-UUID>-2
credentials-file: .cloudflared/credentials-2.json
noTLSVerify: true
The biggest change will be in bin/tunnel
file:
#!/usr/bin/env bash
while getopts ":n:" opt; do
case ${opt} in
n)
echo "Running tunnel #$OPTARG"
suffix="-${OPTARG}"
;;
:)
echo "Invalid option -$OPTARG: specify a tunnel number" 1>&2
exit 1
;;
esac
done
cloudflared tunnel --config .cloudflared/config${suffix}.yml --url localhost:3000 run <Tunnel-NAME>${suffix}
With this setup we can start default tunnel using:
$ bin/tunnel
And to start additional tunnels we can add -n
option with tunnel number:
$ bin/tunnel -n 2
Running tunnel #2
With this setup you can have as many tunnels as you need. All of them will have permanent public URL and they can be easily used by your team members without additional setup. And it’s all free!
If want to hear more from me follow me on Twitter. I tweet about my journey of building and growing Shopify apps and about Ruby on Rails development.