I had a product with a web app, API, worker, engine, Redis, Temporal, QuestDB, Meilisearch, ClickHouse, Signoz, and a few internal tools. The default internet answer was Kubernetes. I used Uncloud on one VPS instead. That was the right call.
Kubernetes would have made this setup look more serious. Uncloud made it ship.
That's the whole thesis.
I had a real system to run: public web surfaces, internal dashboards, background workers, stateful infra, observability, auth in front of private tools, and enough moving parts that "just run Docker Compose" starts feeling a little flimsy. The temptation was obvious: install Kubernetes, wrap everything in Helm charts, and call myself a platform engineer.
I didn't. I used Uncloud.
The shape of the system
This wasn't a toy app. The deployment had:
- public services
- internal services behind auth
- private network-only services
- stateful components like Redis, Postgres-compatible stores, search, and telemetry
The useful part is that I could describe all of it in one uncloud.compose.yml file and deploy slices of the system with one command.
uc deploy --connect "$UNCLOUD_CONNECT" -f deploy/uncloud.compose.yml \
temporal-db temporal temporal-ui redis questdb meilisearch clickhouse signoz nocodb --yes
uc deploy --connect "$UNCLOUD_CONNECT" -f deploy/uncloud.compose.yml \
web api engine worker --yes
That split was deliberate: infra first, app second. No charts. No operators. No "why is my ingress controller talking to cert-manager through a CRD that changed last month?"
Why I didn't want Kubernetes here
Because Kubernetes solves a different problem.
Kubernetes is great when you actually need cluster scheduling, multi-node elasticity, team-level standardization, hard isolation, and all the ceremony that comes with those things. I had one VPS.
On one VPS, Kubernetes mostly gives you a second infrastructure project.
Now you are not shipping your product. You are debugging:
- ingress
- persistent volume behavior
- secrets wiring
- rollout strategy
- Helm drift
- random YAML archaeology
All to end up with the same containers on the same machine.
If the topology is one box, I want software that respects that fact.
That was the whole decision.
What Uncloud gave me instead
The sweet spot was: more structure than raw Docker Compose, much less operational tax than Kubernetes.
I still got:
- service discovery by service name
- public host routing
- private internal networking
- deploy orchestration
- a clean CLI story
And I got it without pretending I was running a small cloud.
A service could talk to Redis at redis:6379, to Temporal at temporal:7233, and to other internal services by name. Public routes lived next to the service definition.
services:
web:
build:
context: ..
dockerfile: deploy/docker/web.Dockerfile
x-caddy: |
app.example.com {
reverse_proxy {{upstreams 3000}}
}
api:
environment:
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=redis://redis:6379
- TEMPORAL_ADDRESS=temporal:7233
That matters more than people admit. Infra gets easier when the topology is legible.
The underrated win: one source of truth
The best part of this setup was not the deploy command. It was the fact that the compose file became an actual contract.
I wrote a small script to parse the environment schemas for each runtime and compare them against the env vars declared in uncloud.compose.yml. If a service was missing a required env var, the script failed fast.
That killed an entire class of production mistakes:
- env added in code, forgotten in deploy
- optional vs required drift
- service config silently diverging from runtime expectations
This is the kind of thing Kubernetes fans often attribute to "platform maturity." You can get a lot of that maturity without signing up for the whole stack.
What changed in practice
Three benefits showed up immediately.
1. Faster deploy decisions
I could reason about the whole system in one file. Public hosts, internal tools, service dependencies, stateful volumes, app services. No hunting across manifests.
2. Lower debugging cost
When something broke, I was debugging the app or the container. Not the app, the container, the ingress controller, the storage class, and the chart values.
3. Much less infrastructure theater
This matters. A lot of teams adopt Kubernetes because it signals scale, not because it solves a present problem. For a single-machine deployment, the extra abstraction is often just prestige debt.
What I gave up
A few real things:
- a more standardized path if I were handing the system to a Kubernetes-native infra team
- stronger primitives for horizontal scaling later
- access to the broader Kubernetes ecosystem
Those are real tradeoffs. I just didn't need them yet.
And that's the part people skip. The question isn't "is Kubernetes more powerful?" Obviously yes. The question is whether you need that power now, on this topology, for this team.
For me, the answer was no.
I'd do it again
If I have one VPS and a serious product, I will take Uncloud over Kubernetes again without hesitation.
Not because Kubernetes is bad. Because unnecessary control planes are bad.
The more I build, the more I like infrastructure that matches the size of the problem. On one machine, I want one-machine tools. Uncloud gave me enough structure to run a real system without paying the Kubernetes tax early.