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:
bash
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 8585
automate.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:
code
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:
code
Error 1033: Cloudflare Tunnel error
Even re-logging in or exporting the certificate path didn’t help for long:
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.pem conflicts 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-tunnel or automation-tunnel)
Copy the provided installation command — it’ll look like this:
bash
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:
bash
sudo apt install cloudflared
Then paste the command you copied earlier:
bash
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:
bash
sudo systemctl status cloudflared
or
bash
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:
bash
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 API
https://automation.example-two.com → should proxy to your n8n instance
To confirm both connectors are live:
bash
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:
bash
http://n8n:5678
To make this work:
Add cloudflared to the same Docker network
Or keep using localhost:<port> if the container is exposed to the host
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.