In this guide, youâll learn how to securely share an application running on your server onto the internet using a Cloudflare Tunnel! This guide has been updated and simplified.
Why Use Cloudflare Tunnel?
- Share local applications youâve built with other people
- Host applications from home servers without port forwarding
Alternatives to Cloudflare Tunnel
- ngrok is another option, but it requires a paid plan for custom domains and persistent URLs. Itâs easy to use but not as flexible as Cloudflare Tunnel. Note that ngrok is no longer open source. You can expect the free plan to be similar to Cloudflareâs TryCloudflare service.
- tailscale is a popular closed source alternative. Iâve heard good things about it, but Iâve never tried it myself. Tailscale offers a tunnel-like feature that they call a Funnel.
- headscale is an open-source alternative to Tailscale. You have to host it yourself.
- pangolin is another open-source alternative. You can host it yourself or pay for their cloud service.
Prerequisites
Before we begin, ensure you have:
- SSH access to your server
- A Cloudflare account (free tier works perfectly)
- A domain name (optional)
Installing cloudflared
Important: Please note itâs called cloudflared (with a âdâ at the end). Donât let it trip you up!
Below are installation instructions for debian-based Linux distros. For other distros or operating systems, check the official Cloudflare documentation. As of this writing, the URL for the official documentation is located here.
- Add Cloudflareâs package signing key:
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | sudo tee /usr/share/keyrings/cloudflare-public-v2.gpg >/dev/null
- Add Cloudflareâs repository to apt:
echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
- Update your package list and install cloudflared:
sudo apt-get update && sudo apt-get install cloudflared
- Verify successful installation:
You should see version information like cloudflared version 2025.x.x confirming successful installation.
cloudflared --version
Explanation:
- Package signing verification: The signing key ensures youâre installing authentic Cloudflare software, not malware.
- Repository integration: Adding Cloudflareâs repository to
aptallows automatic updates through your usualapt upgradecommand. - System-wide installation: Places
cloudflaredin/usr/local/bin/making it accessible to all users and system services.
Instant Tunnels with TryCloudflare
Cloudflare has two options for setting up a tunnel. Weâll look at the easiest one first. Cloudflare calls this TryCloudflare. You likely wonât be using this for your server because of the reasons below, but itâs good to know about it in case you ever need to spin something up quickly.
Pros
- No account needed
- No configuration needed
- HTTPS by default
- DDoS protection
Cons
- Changes to a new random URL every time you restart the tunnel
- Maximum 200 concurrent request limit
- No uptime guarantee (Designed for testing only, not production workloads)
- Server-Sent Events streaming is not supported
- No persistence (Tunnels disappear when you close the terminal or reboot)
Starting a TryCloudflare Tunnel
cloudflared tunnel --url http://localhost:8080
Cloudflare generates a random URL like https://seasonal-deck-organisms-sf.trycloudflare.com. This URL points to your local application running on port 8080.
Persistent Tunnels
Now weâll go into persistent tunnels. This is what youâll want to use for your server. Persistent tunnels require a Cloudflare account and some setup.
Step 1: Custom Domains
To use Cloudflare Tunnel with your own domain, you have two options:
Option A. Full DNS Setup
For full DNS setup, you need to switch your domainâs DNS entirely to Cloudflare. Doing this provides the following benefits:
- Automatic DNS management: Cloudflare automatically creates and manages DNS records for new tunnels, so you donât have to manually create DNS records
- Dashboard: You can use the dashboard on Cloudflareâs website to manage DNS, tunnels, and security policies
- Global load balancing: Traffic to your application is distributed across multiple servers automatically
Option B. Partial DNS Setup
Important: Partial DNS setup requires a paid Cloudflare plan.
You can use Cloudflare Tunnel with other DNS providers (eg. Namecheap, Porkbun, etc) by manually creating DNS records:
- DNS record type: CNAME (or ALIAS for root domains)
- Record name: Your subdomain (e.g.,
appforapp.yourdomain.com) - Record value:
subdomain.yourdomain.tld.cdn.cloudflare.net
Generally speaking, youâll want to use the full DNS setup. If you prefer to keep your existing DNS provider, you must manually create DNS records that point to Cloudflare. I assume you will be using the full DNS setup for the rest of this guide.
Step 2: Different Methods to Create Persistent Tunnels
Cloudflare offers two ways to create persistent tunnels: using their online dashboard or using the command line. Note that the online dashboard method still requires you to use the command line, just to a lesser degree.
Option A. Dashboard Method
Pros:
- Graphical interface: Itâs a bit easier for beginners to use.
- Remote management: Configure and monitor tunnels from anywhere without server access
- Built-in monitoring: Real-time connection status and traffic analytics
Cons:
- Doesnât avoid the terminal: You have to switch back and forth between the browser and the terminal.
Process:
- Navigate to Zero Trust dashboard â Networks â Tunnels
- Click âCreate a tunnelâ â Choose âCloudflaredâ connector
- Name your tunnel (e.g., âproduction-web-serverâ, âdev-api-serverâ)
- Copy the provided installation command containing your unique tunnel token
- Run the command on your server
Option B. Command Line Method
Pros:
- Configuration files can be version-controlled with Git
- More control over tunnel parameters and routing rules
Cons:
- More setup is needed
Why I prefer the CLI method: I prefer the CLI method because the dashboard approach:
- Hides important details for understanding how Cloudflare tunnels work
- Requires switching between terminal and browser
- Is relatively new and may change
For these reasons, weâll focus on the command-line interface (CLI) method below.
Step 3: Creating a Tunnel
Authenticate with Cloudflare
cloudflared login
- This command will display a URL such as:
https://dash.cloudflare.com/argotunnel?callback=.... - Open this URL in a browser.
- Authenticate by logging into your Cloudflare account and grant tunnel creation permissions.
- The
cloudflaredCLI tool creates a certificate file at~/.cloudflared/cert.pem.
Security consideration: This certificate authorizes tunnel creation for your Cloudflare account. Treat it like a password.
Create Your Tunnel
-
Create a new tunnel with a descriptive name. This can be used to manage the tunnel later. This creates a JSON file containing tunnel-specific authentication tokens located at
~/.cloudflared/[tunnel-uuid].json. Youâll need this file path later.cloudflared tunnel create your-tunnel-name -
List all tunnels and verify your new tunnel was created. Youâll see a unique identifier (eg.
ed5bfe16-cb5f-449c-b2e9-7c300b749c79) for the tunnel. This is the tunnel UUID, which youâll need later.cloudflared tunnel list
Step 4: Server Configuration File (CLI Method)
-
Create a new configuration file with your preferred text editor.
vim ~/.cloudflared/config.yml -
From here on out weâll assume the tunnel UUID is
ed5bfe16-cb5f-449c-b2e9-7c300b749c79. Make sure to replace this with your own tunnel UUID in the following steps. -
Add the following to the
config.ymlfile. The tunnel-UUID is the UUID of the tunnel you created earlier. Change the port in the url to the service you want to exposed to the internet. Thecredentials-fileshould point to the absolute path of the JSON file created when you made the tunnel.url: http://localhost:8188 # Change to the local service you want to expose tunnel: ed5bfe16-cb5f-449c-b2e9-7c300b749c79 # Change to your tunnel UUID credentials-file: /home/yourusername/.cloudflared/ed5bfe16-cb5f-449c-b2e9-7c300b749c79.json # Change to your credentials file path
Step 5: Configure the Tunnel DNS Route (CLI Method)
-
Now weâll link the tunnel to a custom domain or subdomain. The format is
cloudflared tunnel route dns <tunnel-uuid-or-name> <hostname>. Replace<tunnel-uuid-or-name>with your tunnelâs UUID or the name you gave it earlier. Replace<hostname>with the domain or subdomain you want to use (eg.app.yourdomain.com).cloudflared tunnel route dns ed5bfe16-cb5f-449c-b2e9-7c300b749c79 app.example.com -
From here on out weâll assume youâre using
app.example.comas your hostname. Make sure to replace this with your own hostname in the following steps.
Explanation:
- The command creates a CNAME record that points
app.yourdomain.comto<tunnel-uuid>.cfargotunnel.com
Step 6: Running the Tunnel
-
Start the tunnel using the configuration file you created earlier. You can use the tunnel UUID or the tunnel name.
cloudflared tunnel --config ~/.cloudflared/config.yml run ed5bfe16-cb5f-449c-b2e9-7c300b749c79 -
You can also add the
loglevelflag for detailed logs.cloudflared tunnel --loglevel info --config ~/.cloudflared/config.yml run ed5bfe16-cb5f-449c-b2e9-7c300b749c79 -
If your internet service provider (ISP) doesnât support QUIC (eg. Shaw Internet in Canada), you will need to specify HTTP/2 protocol instead. QUIC is a new protocol for HTTP/3.
cloudflared tunnel --protocol http2 --config ~/.cloudflared/config.yml run ed5bfe16-cb5f-449c-b2e9-7c300b749c79 -
Next, go to
https://app.example.comin your browser. You should see your local application being served over HTTPS. If this works, pat yourself on the back because you just successfully set up a Cloudflare Tunnel!
Step 7. Check Tunnel Status
-
You can check the tunnel status
cloudflared tunnel info ed5bfe16-cb5f-449c-b2e9-7c300b749c79 -
You can also monitor live connection logs
tail -f ~/.cloudflared/cloudflared.log
Troubleshooting
âFailed to create new quic connectionâ
This could either be because your firewall is blocking one of the ports cloudflared uses, or your ISP is blocking QUIC traffic. If you live in Canada, Shaw Internet blocks QUIC traffic by default as of this writing.
- If youâre running Ubuntu on your server, itâll be using UFW (Uncomplicated Firewall) as its firewall by default. Check if UFW is blocking port
7844, which is used by Cloudflare.
sudo ufw status verbose
# If port 7844 is not allowed, run the following to allow it:
sudo ufw allow out 7844/udp
- To find out if your ISP blocks QUIC, youâll have to search your ISPâs website. If your ISP is indeed blocking QUIC, you can force cloudflared to use HTTP/2 instead, which is more firewall-friendly.
- QUIC provides better performance but itâs quite new and some ISPs block it. HTTP/2 over TCP is more universally supported.
# Force HTTP/2 protocol instead of QUIC
cloudflared tunnel --protocol http2 --config ~/.cloudflared/config.yml run your-tunnel-name
âCannot determine default configuration pathâ
This may be because you did not specify the path to your configuration file.
# Correct command with explicit config path
cloudflared tunnel --config ~/.cloudflared/config.yml run ed5bfe16-cb5f-449c-b2e9-7c300b749c79
Quick Reference
Tunnel Commands
- Run an existing tunnel over HTTP/2.
cloudflared tunnel --protocol http2 --config ~/.cloudflared/config.yml run <Tunnel-UUID> - Lists all tunnels.
cloudflared tunnel list - Find what port a tunnel is running on.
cloudflared tunnel info <Tunnel-UUID> - Create a tunnel.
cloudflared tunnel create <name> - Delete a tunnel.
cloudflared tunnel delete <name> - Add a DNS record to a tunnel.
cloudflared tunnel route dns <Tunnel-UUID> <hostname> - Remove a DNS record from a tunnel.
cloudflared tunnel route remove <Tunnel-UUID> <hostname>
Restricting Access to Your Tunnel
One feature of Cloudflare tunnels I find particularly useful is being able to restrict access to your tunnel without configuring authentication on your local application.
You set this up inside the Cloudflare dashboard.
You can restrict access to your tunnel in different ways:
- Restrict via OTP (One-Time Password) login handled by Cloudflare
- Restrict to certain IP addresses
- Restrict to certain geographical locations (not covered here)
- Restrict via Cloudflare Access Groups (not covered here)
For instance, you have application A that you want to demo to client A and you have application B that you want to demo to client B. You donât want to spend time setting up authentication since theyâre just demo applications, but you do want them to be restricted to the intended client. You can point application A to a.example.com and application B to b.example.com. You then set an OTP access policy on a.example.com that only allows client Aâs email address and another for b.example.com.
Setting up access restrictions
These instructions are accurate as of November 2025, but Cloudflareâs dashboard may change.
- Go to the dashboard on Cloudflareâs website.
- Go to the Zero Trust dashboard: https://one.dash.cloudflare.com
- Click âAccessâ then âApplicationsâ
- Click âAdd an applicationâ then select âSelf-hostedâ
- Fill out the following in the âConfigure Applicationâ form:
- Application name:
your-tunnel-name - Session Duration:
24 hours- This is how long users can stay logged in before needing to re-authenticate.
- Application domain:
app.yourdomain.com - Leave everything else as default.
- Application name:
- Now fill out the following in the âAdd Policiesâ form:
- Policy name:
your-tunnel-name - Selector:
- Email: Enable email OTP login. âValueâ would be the you allow access to the tunnel.
- IP Ranges: Enable IP allowlisting. âValueâ would be the IP addresses.
- Policy name: