I build a SaaS infrastructure SDK — the auth, billing, workspaces, and quota layer that basically every app rebuilds from scratch. We run our own products on it (PlugNode, AgentCenter, Imejis), so it's the same stack in production behind real apps, not a demo.
The recurring request from developers was self-hosting. A real chunk of them won't put their users' data on someone else's cloud - compliance, control, or just preference. For an infra product that's not a nice-to-have, it's a market you either serve or you don't.
The problem is self-hosting is usually where these tools fall apart. You hand someone a pile of services and a 40-step guide, and you lose them around step 6. So I set a hard target: clone a repo, fill in three secrets, run one command, full stack up on your own infrastructure.
Here's what it actually took, and what surprised me.
The infra work was the easy part. One Docker Compose file wires all the services together - app server, client dashboard, auth portal, MongoDB, Redis - so nobody has to connect them by hand. The flow ends up being: clone, copy the env template, generate four secrets with openssl, compose up. That part went how I expected.
The trust work was the real work. People self-host specifically to keep their data in-house, so "your data never leaves your machine" had to be literally true, not a marketing line. That meant splitting the control plane from the data plane: the licensing/control server stays cloud-managed and the self-hosted stack only ever contacts it to validate a license. It never sends application data out. Getting that boundary clean — and being able to say it plainly — was the actual unlock. If a self-hoster can't trust that claim, none of the convenience matters.
The hardest part was resisting the urge to make the README sound easier than reality. Local is one command. Production is not. Production needs unique secrets (not the local-dev fallbacks), real HTTPS URLs, TLS termination, load-balancing replicas with sticky sessions, and your own database backups. The tempting move is to bury all that and lead with "deploy in 10 seconds." I listed every production step instead.
That felt counterintuitive at first — won't honesty about the work scare people off? But honest setup docs build more trust than a slick claim that breaks on a real server. The founders evaluating an infra product are exactly the people who'll resent being told production is trivial when it isn't. Under-promising on setup difficulty has been a better filter than a flashier promise would've been.
One more thing I'm still chewing on: pricing. I landed on pricing self-hosted at parity with cloud rather than charging more, because self-hosters already pay for their own infra and their own ops time. Charging a premium on top of that felt like punishing the customers who are doing more of the work themselves. Curious if anyone's found the opposite to be true (not final.. but still looking into it.).
Zero external paying customers so far — I'm being honest about that too. This is groundwork, not a victory lap. But removing the self-hosting friction felt like clearing one of the real blockers between "interested dev" and "running it in production."
If you're building anything where setup friction sits between people and your product's value, the lesson that's stuck with me: make the easy path genuinely one command, and be ruthlessly honest about where the easy path ends.
Repo's open and MIT licensed if you want to see how it's wired:
github.com/buildbase-app/self-hosted-starter