(Early draft - just published in order to appear first in this series)
Description
A reference stack for hosting multiple websites with Nginx, Squidex, and .NET — not a framework, not a library, just a working example you can understand and own.
Every time I set up a new hosted website I found myself doing the same thing:
Copying configuration, rewiring environment files, and reconnecting the same five moving parts.
It worked, but it was fragile knowledge — living in each hand-tailored repos rather than in the open.
The obvious fix seemed like a framework. Abstract the repetition, publish a package, done.
But I kept hesitating.
The Framework Trap
A framework makes decisions for you. That's its value — until it isn't.
The moment the framework's opinion diverges from your requirement, you're fighting the abstraction instead of solving the problem.
And with something as infrastructure-heavy as a hosting stack, the divergence happens early.
I didn't want to maintain a framework. I wanted to understand my own setup well enough that adding a new site was boring.
So instead of a framework, I built Polyhost — a reference stack. A working example you fork, read, and adapt. No package to install, no CLI to run, no magic to debug.
What Polyhost Is
Polyhost is a Docker Compose setup for hosting multiple websites from a single server. Five services, wired together:
- Nginx — reverse proxy routing traffic to the right backend
- Squidex — headless CMS backing content for all hosted sites
- MongoDB — Squidex's data store
- .NET backend — ASP.NET Core handling contact forms, enrollments, sitemaps
- Dev shell — a Debian container with .NET, Elm, and Node for local development
The philosophy is simple: adding a new hosted site should be configuration, not reinvention.
Routes go in Nginx config. Content schemas go in Squidex. Business logic goes in the .NET backend. The plumbing is already there.
Why a Reference Stack and Not a Framework
A reference stack is honest about what it is. You can read every line. You can delete what you don't need. You own it the moment you fork it.
It's also better for AI tooling. A clear, well-structured example is something a language model can reason about, explain, and help you extend. A clever abstraction layer is something it has to reverse-engineer.
Polyhost is MIT licensed — take it, change it, ship it. The only ask is that you keep the copyright notice in the repo.
Who This Is For
Polyhost is for developers who:
- Self-host a handful of client or personal sites
- Want a repeatable setup without buying into a full PaaS
- Are comfortable with
Docker Composeand want to understand what they're running - Would rather read a working example than absorb a framework's documentation
It is not for teams running hundreds of sites or needing enterprise-grade multi-tenancy. For that, look at Kubernetes or a managed platform.
What's Coming
This is the first article in a series walking through Polyhost end to end:
- Why I Built a Reference Stack Instead of a Framework ← (you are here)
- Setting up the dev environment
- Nginx config — routing multiple domains from one proxy
- Squidex — structuring content for multiple sites
- The .NET backend — contact forms, sitemaps, and CMS integration
- Adding a new site — the whole workflow from zero
The project is open source on GitHub. If you find something broken or have a question, open an issue.
Top comments (0)