Cloudflare Tunnel Tutorial – Expose Web Services to the Internet

Expose Web Services to the Internet with Cloudflare Tunnel

Imagine working on a web service on your local computer, and you want somebody outside your network to access it on their PC. You have several options you can use to achieve that.

You could decide to purchase a hosting service, such as a server and configure all DNS settings to make the service available on the public internet.

If you decide to use containerization like Docker, Kubernetes, etc., you will need to set up even more configurations. That includes configuring ACLs, GRE tunnels, and rotating IP addresses.

But why all that hustle when you can easily expose your locally hosted web service using Cloudflare Tunnel?

Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address. With Tunnel, you do not send traffic to an external IP — instead, a lightweight daemon in your infrastructure (cloudflared) creates outbound-only connections to Cloudflare’s edge, allowing you to expose your localhost to the internet.

This tutorial will cover how to use Cloudflare Tunnel to create and manage tunnels to expose web services from a computer to the internet.

Let’s dive in and see how to create a tunnel with Cloudflare.

Step 1: Create a Cloudflare Account and Add a Domain

Creating an account on Cloudflare is not a complicated process. Navigate to the official Cloudflare Dashboard and sign up with your email account. When done, make sure you check the verification email that Cloudflare will send to your inbox.

In the Cloudflare dashboard, you will see a section similar to the image below requesting you to add a new site. That shouldn’t sound complex; they simply want you to add a domain name to your site. Click the “Add Site” button.

word image 45

A new screen will appear, and you will see a textbox to type in the new domain name. Enter your domain name and click “Add Site.

Note: You need to enter a registered domain name, and you shouldn’t use a subdomain. For example, if we have the registered domain as “,” we cannot use a subdomain like “”

add website to cloudflare

You will see an option to select a pricing plan that you want to use. There are four plans to choose from – Pro, Business, Enterprise, and Free. We will stick to the free plan. Scroll to the bottom of the window, select the Free Plan, and click Continue.

choose free cloudflare plan

You will be prompted to review your DNS records on the next screen. Luckily, Cloudflare will generate a report on what steps to take.

For example, if you had already set up a site for your domain and even added the nameservers to your domain registrar, you will need to change these nameservers and add the ones provided by Cloudflare.

After successfully setting up your domain, we can now proceed to step two, where we will download cloudflared – a command-line client for Cloudflare.

cloudflared stands for Cloudflare Daemon. In Linux, a daemon is a process that runs in the background and performs tasks that are requested by other programs.

Step 2: Download and Install Cloudflared

Cloudflared is available for various platforms, including Linux, Windows, and macOS. For this post, we assume that you are running a Linux distribution. There are different Cloudflared packages depending on your Linux distro.

Debian-based distributions

wget -q
sudo dpkg -i cloudflared-linux-amd64.deb

word image 48

RHEL-based distributions

wget -q
sudo dpkg -i cloudflared-linux-amd64.deb

Alternatively, you can manually download the cloudflared installation file for your distribution on the official Cloudflared GitHub page. After a successful installation, you can confirm the Cloudflared version running on your system by executing the command below.

cloudflared version

word image 49

Step 3: Connect Your Cloudflare Account

Up to this point, we have our domain fully set up on the Cloudflare account and the cloudflared command-line tool running on our system. Now, we need to synchronize these two services. Execute the command below on your Terminal.

cloudflared tunnel login

Your browser will open, and you will need to select a domain that you wish to authorize and use to create a tunnel. If the browser doesn’t open, copy the link generated on the Terminal and use it to access the Cloudflare dashboard.

word image 50

You will see a prompt to select a domain to authorize a Cloudflare tunnel. Even though you don’t need to choose the right domain here. However, I highly recommend authorizing a domain you want to tunnel on. For example, you can select a domain like, and later on, you can create a tunnel on a subdomain like

authorize cloudflare tunnel

If the tunnel was successful, you should see a pop-up similar to the image below.

successfully authorized cloudflare tunnel message

You should also see a similar message on your Terminal.

word image 53

Step 4. Create Your First Tunnel

After a successful login, you are now ready to create your tunnels. Execute the command below to create your first tunnel.

Note: You can name this tunnel as you wish. In our case, we decided to call it TunnelOne.

cloudflared tunnel create TunnelOne

After executing the command above, you will get two vital pieces of information that we will need later.

  • The path to the .json file that holds our tunnel credentials.
  • The tunnel ID.

word image 54

Step 5. Create a Configuration File

Up to this point; you can actually go ahead and run your tunnel. However, we wouldn’t recommend that yet! To make things easier, we suggest creating the configuration file and setting up a systemd service to control your tunnels. With that in mind, let’s get started.

First, create a directory called cloudflared inside the /etc. directory by executing the command below.

sudo mkdir /etc/cloudflared

Navigate inside the cloudflared directory and create a configuration file called config.yml.

cd /etc/cloudflared
sudo touch config.yml

word image 55

Now, we need to set tunnel ID and the path to the credentials file inside our configuration file. To do so, open the configuration file using the command below.

sudo nano /etc/cloudflared/config.yml

Add the details as shown below:

tunnel: 35b39cd0-f65d-4002-83f5-50d182b1ca0e
credentials-file: /home/ubuntu-user/.cloudflared/35b39cd0-f65d-4002-83f5-50d182b1ca0e.json

word image 56

Note: Beware of formatting! Ensure the details are formatted as shown in the image above. Additionally, if you are unsure of the details, you can just navigate to the .cloudflared/ in your home directory (cd .cloudflared/) directory and see the contents of the .json file. When done, save the file (Ctrl + S) and exit (Ctrl +X).

Step 6. Setup Ingress Rules.

To better understand ingress rules, we first need to start a web service that we want to tunnel to the public internet. If you don’t have one yet, there are several ways you can start a web service.

Ingress is the process of transferring data into a network. In this context, when talking about Cloudflare, ingress is the process of transferring data into a Cloudflare-protected domain.

Start a Python Server

You can create a simple file server with Python by executing the command below on your Terminal.

python3 -m http.server 5555

word image 57

Feel free to change the port number to any port number you wish.

To run the simple Python server in the background you can run:

python3 -m http.server 5555 &> /dev/null &

Install Apache Web Server

Another alternative is to install a full-featured web server like Apache. By default, Apache will run on port 80.

Execute the command below to install Apache for Debian-based systems.

sudo apt install apache2

Next start Apache:

sudo service apache2 start

apache debian default page

Start an Application (Simple Website/WordPress/ReactJS/NodeJS/etc)

If you are a web developer well-versed with various Javascript frameworks and libraries, you can easily set up a ReactJS application to run on a specific port on your system.

We will use Apache and Python3 file-server to test the Cloudflare tunnel for this post.

Now that we have the web service we want to tunnel up and running, we can dive into setting up ingress rules.

Ingress rules enable Cloudflared to direct a request to a particular service running on your localhost. For example, we have two web services running on our system:

  • The Python file server (Running on port 5555)
  • The Apache Web server (Running on port 80).

We will tunnel these two services separately, each on its unique sub-domain with the help of ingress rules. Inside the /etc/cloudflared/config.yml file, add the lines below.

You will also notice that we added one line at the bottom (service: http_status:404). That instructs Cloudflare to serve a blank page if the requested request is not available.

 - hostname:
   service: http://localhost:80
 - hostname:
   service: http://localhost:5555
 - service: http_status:404

Remember to edit the hostname and service accordingly. When done, your /etc/cloudflared/config.yml file should look similar to the image below. Save (Ctrl + S) the file and exit (Ctrl + X).

word image 59

Step 7. Setup Cloudflared systemd Service

The last step we need to carry out before we can now run our tunnel is setting the cloudlfared systemd service. That will enable us to control the cloudflared service with much ease. You can start, stop, restart, enable and disable cloudflared. Execute the command below to install the cloudflared service.

sudo cloudflared service install

word image 60

After a successful install, you can now control the cloudflared service using the commands below.

sudo systemctl enable cloudflared
sudo systemctl disable cloudflared
sudo systemctl start cloudflared
sudo systemctl stop cloudflared

You can check the logs by running the command below.

sudo journalctl -u cloudflared

You can enable and start cloudflared:

sudo systemctl enable cloudflared
sudo systemctl start cloudflared

word image 61

If everything was correctly set up, your tunnel should now be connected. You can confirm that by executing the command below.

cloudflared tunnel info mytunnel

Step 8. Start Cloudflare Tunnel

Up to this point, you have everything set up successfully, and you can now start the routing process. The process is much easier than you might imagine. Execute the command below, replacing with your sub-domain.

Create a Tunnel for the Apache Web Server

cloudflared tunnel route dns TunnelOne

Create a Tunnel for the Python File Server

cloudflared tunnel route dns TunnelOne

word image 62

When you head over to the Cloudflare dashboard, you will notice that cloudflared automatically added CNAME records for these two sub-domains. See the image below.

cloudflare dns records showing cnames added by cloudflare tunnel

Wait for a few seconds for the DNS to update then open the subdomains on your browser.

visiting tunnel subdomains we just added in browser and confirming it works

Tip: If the DNS records are taking long to update and you cannot access the subdomains on your normal web browser, try using the Tor Browser.

Step 9. Managing Tunnels

To list all the tunnels create on your system, execute the command below:

cloudflared tunnel list

word image 65

To delete a tunnel, execute the commands below:

cloudflared tunnel cleanup [ tunnel_ID or tunnel_Name ]
cloudflared tunnel delete [ tunnel_ID or tunnel_Name ]

word image 66

Note: After deleting a particular tunnel, remember to delete any CNAME records associated with it in the Cloudflare dashboard.

Frequent Issues

System has not been booted with systemd as init system (PID 1). Can’t operate.

This error is common when using WSL on Windows.

If you get this error when starting cloudflared then use:

sudo service cloudflared start


This post has given you a step-by-step guide on exposing a web service from your localhost to the internet with Cloudflare tunnel. At this point, you can now explore more by creating more tunnels, tweaking the ingress rules, and much more. Feel free to go through the official Cloudflare documentation.

If you encounter any error carrying out any of the steps described above, please feel free to hit the comments section.

Notify of
Receive notifications when your comment receives a reply. (Optional)
Your username will link to your website. (Optional)

Inline Feedbacks
View all comments
You May Also Like