Run Multiple Cloudflare Tunnels on a Single VPS Effortlessly
Learn how to efficiently manage multiple domains with Cloudflare tunnels on one Ubuntu server without complex setups.

☁️ Cloudflare Edge Development Guides
Complete Cloudflare guides with practical examples, deployment strategies, and developer prompts to help you build and ship edge applications faster.
If you’ve followed my previous guide on exposing Docker containers with Cloudflared and no open ports, you’ve seen how easy it is to set up a single Cloudflare Tunnel for one domain.
But things get tricky once you try to manage multiple domains or zones from the same VPS.
I recently needed to run two separate domains — each with its own Docker services — behind Cloudflare Tunnels on a single Ubuntu server. That’s when I discovered how limited the traditional CLI setup is for multi-zone configurations, and how moving to Cloudflare’s remotely managed tunnels completely fixes the problem.
This article walks you through the exact setup, what went wrong, and how to do it the right way.
Problem: Only One Zone Authenticated per VPS
When you first authenticate Cloudflared using:
cloudflared login
Cloudflare issues a file called cert.pem and ties it to one specific zone. That file lives in ~/.cloudflared/ and all your tunnels rely on it.
So if you have:
api.example-one.com→ Port 8585automate.example-two.com→ Port 5678
You quickly run into problems because the CLI tools assume a single zone per certificate.
When I tried to link my second tunnel to another domain, I kept hitting this message:
INF example-two.com is already configured to route to your tunnel tunnelID=c101ebf4...
Or worse, when switching certs, the existing tunnels broke entirely with:
Error 1033: Cloudflare Tunnel error
Even re-logging in or exporting the certificate path didn’t help for long:
export TUNNEL_ORIGIN_CERT=/home/user/.cloudflared/cert.pem
Eventually, I realized this setup simply isn’t meant for multiple zones.
The Wrong Approach (and Why It Fails)
Here’s what I tried, and what failed along the way:
| Attempt | Command / Action | Outcome |
|---|---|---|
| Created multiple tunnels via CLI | cloudflared tunnel create name | Each tunnel tied to one zone only |
Tried to rerun cloudflared login | Switched zone but broke existing tunnel | |
Added multiple config files in /etc/cloudflared | Only one could be active at a time | |
Used --config and --credentials-file flags | Some flags unsupported by service install | |
| Installed as a systemd service manually | Worked for one tunnel, not multiple | |
Ran tunnels with sudo | Lost TUNNEL_ORIGIN_CERT path, missing cert.pem | |
| Got 1033 error | Tunnel connected but no matching route in DNS |
At that point, it was clear: the CLI + cert.pem model is designed for single-zone setups. The fix was to switch to the modern, token-based (remotely managed) approach.
Solution: Manage Each Tunnel via the Cloudflare Dashboard
The modern approach uses Cloudflare Zero Trust to manage tunnels remotely. Instead of dealing with local certificates, you connect each tunnel via a unique token.
This allows you to:
- Run multiple tunnels (one per domain) on the same VPS
- Keep all zones authenticated in the dashboard
- Manage routing (CNAMEs, hostnames, ports) centrally via UI
- Avoid
cert.pemconflicts or 1033 errors
Step 1: Create a New Tunnel in Cloudflare Zero Trust
- Go to Cloudflare Dashboard → Zero Trust → Networks → Tunnels
- Click Create a Tunnel
- Choose Cloudflared
- Name your tunnel (e.g.,
api-tunnelorautomation-tunnel) - Copy the provided installation command — it’ll look like this:
sudo cloudflared service install eyJhIjoiMWFhY2Y4Y...
That eyJ... string is your tunnel token — a secure way to authenticate the tunnel to Cloudflare without a cert.
Step 2: Run the Tunnel on Your VPS
If Cloudflared isn’t installed yet:
sudo apt install cloudflared
Then paste the command you copied earlier:
sudo cloudflared service install eyJhIjoiMWFhY2Y4Y...
This automatically installs a system service (cloudflared) that connects your server to Cloudflare and starts at boot.
You can verify it’s connected by checking:
sudo systemctl status cloudflared
or
cloudflared tunnel info
Step 3: Add a Public Hostname (Map to Your Docker Service)
In the Cloudflare dashboard:
- Open your new tunnel
- Scroll to Public Hostnames
- Click Add a public hostname
Fill in the following:
| Field | Example | Description |
|---|---|---|
| Subdomain | api | For api.example-one.com |
| Domain | example-one.com | Choose from dropdown |
| Type | HTTP | |
| URL | http://localhost:8585 | Your Docker container port |
| Path | (leave blank) | Optional if you want full domain routing |
Then click Save hostname
📸 Screenshot opportunity #1 — Add Public Hostname form
Repeat this process for every local service or domain you want to expose.
Step 4: Add Another Tunnel for Another Zone
To connect a second domain (different zone):
- Go back to Tunnels → Create a Tunnel
- Repeat the steps above (new token, new tunnel name)
- Run the second install command on the same VPS
Example:
sudo cloudflared service install eyJhbGciOiJIUzI1...
Then add a new public hostname for that zone, such as:
| Hostname | Port | Description |
|---|---|---|
automation.example-two.com | 5678 | Dockerized n8n instance |
📸 Screenshot opportunity #2 — multiple tunnels in Cloudflare dashboard
Cloudflare will manage both tunnels independently, each linked to its zone.
Step 5: Test Everything
Once both tunnels are running, visit your domains:
https://api.example-one.com→ should proxy to your local APIhttps://automation.example-two.com→ should proxy to your n8n instance
To confirm both connectors are live:
cloudflared tunnel list
You should see both tunnel IDs listed and connected.
Common Errors and Fixes
| Error | Cause | Fix |
|---|---|---|
Error 1033: Cloudflare Tunnel error | Tunnel not running or hostname not mapped | Start cloudflared or add hostname in dashboard |
Cannot determine default origin certificate path | Missing or wrong cert.pem | Not needed for token-based tunnels |
flag provided but not defined: -config | Older cloudflared version | Use --config before run, or upgrade |
wrong zone configured | Tried to route via CLI | Switch to dashboard-based hostnames |
| Tunnel stops when you run another | Same cert.pem reused | Each managed tunnel uses its own token |
Step 6: Optional – Connect to Docker Network by Name
If your services run under Docker with custom networks, you can refer to containers by name:
http://n8n:5678
To make this work:
- Add
cloudflaredto the same Docker network - Or keep using
localhost:<port>if the container is exposed to the host
📸 Screenshot opportunity #3 — Docker network diagram (optional)
Conclusion
If you’re managing more than one domain on a single VPS, don’t fight the CLI. Use Cloudflare’s remotely managed tunnels instead.
This approach removes the one-zone limitation, eliminates cert conflicts, and lets you manage everything visually in the dashboard — one connector per zone, all running side by side on your VPS.
You’ll never have to touch cert.pem or deal with the --config flag again.
Hope this helps other developers who hit the same wall I did when scaling beyond a single domain.
Thanks, Matija