Cfmux is a Golang CLI wrapper for cloudflared that helps manage multiple Cloudflare Tunnel accounts using isolated profiles, runtime separation, and systemd integration.
Most infrastructure tools are born from one thing:
Frustration.
Cfmux started exactly the same way.
For a long time, I used Cloudflare Tunnel through cloudflared for almost everything:
- self-hosted apps
- development environments
- temporary testing
- internal dashboards
- webhook receivers
And honestly?
cloudflared is great.
It is lightweight, stable, simple to deploy, and probably one of the easiest ways to expose local services securely without dealing with public IPs or complicated reverse proxy setups.
But eventually I hit a workflow problem.
Not a technical limitation.
A workflow limitation.
The Problem Wasn't Tunneling
The problem appeared when I started managing multiple Cloudflare accounts.
Something like this:
- personal projects
- client infrastructure
- staging environments
- isolated test environments
- temporary deployments
At first it was manageable.
Then slowly things became messy.
Credential confusion.
Wrong account usage.
Mixed runtime state.
Configs everywhere.
And I realized something important:
I was manually building my own management layer around cloudflared anyway.
So eventually I decided to formalize it.
Enter Cfmux
Cfmux is a lightweight wrapper around cloudflared.
Not a replacement.
Not a competitor.
It still relies entirely on the official Cloudflare tooling underneath.
The goal is actually very small:
make multi-account tunnel workflows cleaner and isolated.
That’s it.
No magic networking layer.
No custom tunnel protocol.
No attempt to reinvent Cloudflare Tunnel.
Just workflow management.
The Core Idea
Instead of relying on one global runtime state, Cfmux isolates everything into profiles.
Example:
~/.cfmux/
├── profiles/
│ ├── personal/
│ ├── client-a/
│ └── staging/
│
└── current-profile
Each profile has isolated:
- credentials
- configs
- runtime state
- services
So switching contexts becomes much safer.
The Difference Sounds Small...
But in practice it changes the workflow completely.
Instead of constantly doing:
cloudflared --origincert path/to/cert.pem tunnel list
You simply do:
cfmux tunnel list
Because the active profile already knows:
- which credentials to use
- which runtime state belongs to which account
- which service belongs to which tunnel
It removes a surprising amount of friction.
One Important Design Decision
From the beginning, I intentionally avoided turning this into:
“another overengineered dashboard project.”
I wanted:
- single binary
- CLI-first
- minimal dependencies
- Linux-friendly
- boring architecture
So the stack became:
- Golang
- Cobra CLI
- YAML
- systemd integration
Very traditional.
Very infrastructure-oriented.
And honestly, I think boring stacks are underrated for infra tooling.
The MVP Was Extremely Small
The first version only focused on four things:
cfmux profile add
cfmux profile use
cfmux tunnel list
cfmux service install
That was enough.
No web dashboard.
No database.
No Kubernetes operator.
Just practical tooling.
One Thing That Surprised Me
The deeper I went into this project, the more I realized:
infrastructure tools live or die from reliability.
Not features.
So instead of aggressively adding functionality, I started focusing heavily on testing.
Especially integration testing.
Things like:
- profile isolation
- runtime separation
- corrupt registry handling
- passthrough execution
- filesystem safety
- drift detection
- config protection
Because infrastructure software stops being “just code” once people trust it with production environments.
Why I Still Respect cloudflared
One thing I want to make very clear:
Cfmux exists because of a workflow gap.
Not because cloudflared is bad.
Actually the opposite.
cloudflared is good enough that I wanted a better management experience around it instead of replacing it entirely.
And honestly?
If Cloudflare eventually adds proper native multi-account workflow management someday, that would be great.
Cfmux was never intended to fight the ecosystem.
It was built to make one specific workflow cleaner.
Installation
Currently installation/update is just:
curl -fsSL https://raw.githubusercontent.com/ExiroStudio/cfmux/main/install.sh | bash
GitHub
Project repository:
GitHub: https://github.com/ExiroStudio/cfmux
My GitHub: https://github.com/ExiroStudio
Final Thoughts
One thing I’ve learned from building this project:
Some of the best software ideas are not revolutionary.
Sometimes they are just:
“this workflow annoys me enough that I should fix it properly.”
And weirdly enough, those projects often become the most useful ones.
Especially when you end up using them yourself every single day.
Top comments (0)