If you are a developer, you know the struggle. You have a project running perfectly on your local machine—whether it is a Next.js app, a React dashboard, a Node.js backend, or a Laravel project—and you need to show it to a client, a teammate, or test it on a mobile device.
In the past, this meant dealing with messy router configurations, port forwarding, or risking security by exposing your public IP address. But there is a modern, secure way to turn your local computer into a server accessible from anywhere in the world: Cloudflare Tunnel.
In this guide, we will walk through exactly how to use Cloudflare Tunnel to securely make any local project public. We will cover everything from the quick, temporary "quick tunnel" method to a permanent, professional setup using your own custom domain. Best of all, we will do this without touching router settings or revealing your IP address.
The Problem: Localhost is Local
When you start a development server, for example, by running npm run dev in a Next.js project, your terminal typically tells you the server is running at localhost:3000. You can open your browser, type in that address, and everything works perfectly.
However, "localhost" literally means your local machine. If you share that URL with a client or a colleague, they won't see anything. That is common sense, but it is a major hurdle for collaboration. To perform client demos, team reviews, or staging tests directly from your own machine, you need a bridge between your local environment and the public internet.
Prerequisites
Before we dive into the tunnel setup, you need a project running locally.
For this guide, we are using a simple Next.js project as an example, but the technique is exactly the same regardless of the framework—Django, Laravel, Node.js, etc.
- Open your project folder in your terminal.
- Run your development server (e.g., npm run dev).
- Verify it is working by visiting localhost:3000 (or your specific port) in your browser.
Now that the app is live locally, let's look at how to expose it.
Part 1: Installing Cloudflare
To use Cloudflare Tunnel, we must install the cloudflared tool on our machine. You can think of this as a Node.js package or a system utility.
For Mac Users
If you are using a Mac, the installation is handled easily via Homebrew. Open your terminal and run: brew install cloudflared
This command allows Homebrew to download and install Cloudflare automatically.
For Windows Users
Windows users can utilize PowerShell or the Command Prompt. The command is: winget install --id cloudflare.cloudflared.
For Linux Users
If you are on Linux, the steps vary slightly by distribution. Debian or Ubuntu systems use a .deb package, while Red Hat or CentOS systems use an .rpm package. Because Linux setups vary, the safest option is to follow Cloudflare's official installation documentation for your specific distro.
Once installed, verify it by running: cloudflared --version
This confirms that the installation was successful.
Part 2: The "Quick Tunnel" (For Temporary Access)
Sometimes you just need a quick link for a 5-minute test. This is where the Quick Tunnel comes in. It is the fastest, easiest-to-visualize technique.
- Open a new terminal window (keep your local server running in the first one).
- Run the following command: cloudflared tunnel --url localhost:3000
Note: Replace 3000 with whatever port your project is running on.
After running this command, scrolling up in the terminal logs will reveal a public HTTPS URL ending in trycloudflare.com. For example, it might look like rising-combinations-getcritical.trycloudflare.com.
If you open this URL on any device connected to the internet, you will see your local app. It is important to note that this is not a deployment. Your code is not uploaded to Cloudflare servers; it is still running on your machine. Cloudflare has simply created a secure route to your local server.
The Limitation: Quick tunnels are temporary. If you stop the command and run it again, you will get a completely new random URL. This makes it great for quick testing, but bad for permanent solutions where you want a fixed domain like demo.example.com.
Part 3: The Permanent Setup (Custom Domains)
For a stable setup where the URL doesn't change, we need to connect the tunnel to a domain we own. This requires a Cloudflare account and a domain managed by Cloudflare's DNS.
Step 1: Add Your Domain to Cloudflare
It does not matter where you bought your domain—GoDaddy, Namecheap, Hostinger, etc.—but the DNS management must be moved to Cloudflare.
- Log in to your Cloudflare account (sign up is free and requires email verification).
- On the dashboard, click Domains and then Onboard a domain.
- Enter your domain name (e.g., rafiudaraj.me).
- Keep the "Quick scan for DNS records" option enabled. This helps import existing subdomains or mail records so your current setup doesn't break.
- Select the Free Plan. This is sufficient for Cloudflare Tunnel.
- Review the DNS records found by the scan. For this tutorial, we won't change existing records; just scroll down and click Continue to activation.
Step 2: Update Your Nameservers
Cloudflare will now provide two nameservers and instruct you to replace your current registrar's nameservers with these new ones. This step gives Cloudflare control over your domain's DNS.
- Log in to your domain registrar (e.g., GoDaddy).
- Navigate to the DNS or Nameservers section for your domain.
- Select the option to use "My Own Nameservers" (custom) rather than the default ones.
- Copy the two nameservers provided by Cloudflare.
- Paste them into the fields in your registrar's dashboard.
- Remove any old nameservers—only the Cloudflare ones should remain.
- Save your changes.
Back in the Cloudflare dashboard, click "I updated my nameservers". This process, called DNS propagation, can take anywhere from a few minutes to 24 hours, though it often finishes in about 5 to 10 minutes. Once the domain shows as "Active" in Cloudflare, you are ready to proceed.
Part 4: Creating the Tunnel via CLI
Now that the domain is active, we return to the terminal to create the permanent infrastructure.
1. Authenticate the CLI
We need to authorize the cloudflared tool to manage our specific domain. Run: cloudflared tunnel login
This will open a browser window. Select your Cloudflare account and grant permission for your specific domain. This tells Cloudflare that your local machine is authorized to manage tunnels for that domain.
2. Create the Tunnel
Run the following command to create a named tunnel (you can name it anything, for example, "nextjs-live"): cloudflared tunnel create nextjs-live
The terminal will output a Tunnel ID, a long hexadecimal string (e.g., starting with 1ed8140...). Crucial: Copy this Tunnel ID. Cloudflare identifies your tunnel by this ID, and we will need it for the configuration file.
3. Route the DNS
We have a tunnel, but no URL points to it yet. We need to create a subdomain (like demo.rafiudaraj.me) and map it to our tunnel. Run: cloudflared tunnel route dns nextjs-live demo (Replace "nextjs-live" with your tunnel name and "demo" with your desired subdomain).
If you check your Cloudflare dashboard DNS section now, you will see a CNAME record for this subdomain pointing to the tunnel.
Part 5: Configuring the Tunnel
We have a tunnel and a domain, but Cloudflare doesn't know what to send through the tunnel yet. We must create a configuration file.
1. Locate the Cloudflare Directory
Cloudflare automatically creates a hidden folder named .cloudflared to store credentials. You can check for it by running ls -a in your home or user directory. Navigate into it: cd .cloudflared.
2. Create the Config File
Create a new file named config.yml. touch config.yml
Open this file in your code editor (e.g., VS Code).
3. Write the Configuration
This file needs three main components: the Tunnel ID, the path to the credentials file, and the ingress rules.
The Credentials File Path: When you created the tunnel, Cloudflare generated a JSON file (e.g., 1ed8140....json) in the .cloudflared folder. You need the absolute path to this file.
- Mac/Linux: Run realpath <filename.json> to get the path.
- Windows: Run Resolve-Path <filename.json> in PowerShell.
The Content of config.yml: Copy the following structure into your file, replacing the ID and path with your own:
tunnel: <YOUR-TUNNEL-ID>
credentials-file: /Users/yourname/.cloudflared/<YOUR-TUNNEL-ID>.json
ingress:
- hostname: demo.rafiudaraj.me
service: http://localhost:3000
- service: http_status:404
Part 6: Running the Permanent Tunnel
With the configuration saved, go back to your terminal. Run the tunnel using the name you gave it: cloudflared tunnel run nextjs-live
As soon as this command runs, Cloudflare reads your config.yml, authenticates using the credentials file, and establishes the secure connection.
You can now open your browser and visit your custom subdomain (e.g., https://demo.rafiudaraj.me). You will see your local application running live on the internet, accessible to anyone.
Important Considerations and Architecture
It is vital to understand the architecture you have just built.
| Feature | Benefit/Requirement |
|---|---|
| Port Forwarding | None Required. Outbound connections keep your public IP hidden. |
| Hardware | Depends on your local machine. If the PC shuts down, the site goes down. |
| Versatility | Framework Agnostic. Works with Node, PHP, Python, etc. |
1. No Port Forwarding Required
Notice that at no point did we log into a router or open port 80 or 443. This works because the cloudflared tool on your computer creates an outbound connection to Cloudflare's edge network. Traffic flows down this established connection, meaning you do not need to expose your public IP address to the world.
2. Dependency on Local Hardware
This is not cloud hosting. Your application is still running on your physical machine.
- If you close your laptop, the site goes down.
- If you stop the cloudflared process, the site goes down.
- If your local internet disconnects, the site goes down.
Because of this, Cloudflare Tunnel is ideal for client demos, internal team tools, staging environments, and testing. It effectively turns your local computer into a small hosting server or VPS without the rental costs, but it is generally not a substitute for a permanent production deployment on a cloud provider.
3. Framework Agnostic
While we used Next.js for this example, this method works for any TCP/HTTP traffic. You can expose a Python Django server, a PHP Laravel app, a plain HTML site, or any other service running on a specific port. You simply need to update the port number in the config.yml file to match whatever your local server uses.
Conclusion
Cloudflare Tunnel offers a sophisticated, secure, and free way to bridge the gap between localhost and the public internet. By moving your DNS to Cloudflare and utilizing the cloudflared CLI, you gain the ability to spin up professional-looking demo links (demo.yourdomain.com) straight from your terminal.
Whether you are freelancing and need to show progress to a client, or you are a developer testing webhooks and mobile responsiveness, this setup is a powerful addition to your workflow.
Note: This guide assumes you are operating on a standard development environment. Always ensure you follow security best practices when exposing local services to the internet.
Community Insights