






















For years my side projects lived on Azure. App Services here, a Static Web App there, a managed SQL database, a sprinkle of Functions, some blob storage, a Communication Services resource for email. Each one made sense the day I created it. Added up over a dozen-plus projects, it became a sprawling estate with a monthly bill that kept quietly creeping — and a mental tax every time I opened the portal and saw resource groups I half-remembered.
This month I moved all of it onto a single VPS. Every API, every static site, every Blazor app, the databases, the object storage, even the transactional email. Azure now shows zero resource groups.
A year ago I wouldn’t have attempted this. It would have been weeks of fiddly, repetitive, error-prone work. But with an LLM coding agent doing the heavy lifting, it turned into something I could knock out in focused sessions between actual product work. That shift is the real story here, so let me walk through what I did, what it cost (and saved), the honest downsides, and why I think this is a no-brainer move for anyone bootstrapping.
The destination is deliberately boring: one solidly-specced VPS, plus a few free or near-free services stitched around it.
systemd services — .NET APIs, Node/Express static frontends, a couple of Blazor WebAssembly apps, an Azure Functions app re-hosted with the Functions runtime, a containerized screenshot service, and a local SQL Server instance alongside a handful of SQLite databases.The whole public surface is fronted by Cloudflare, so I also get caching, DDoS protection, and analytics thrown in without lifting a finger.
The variety is the point — this wasn’t one app, it was a zoo:
systemd unit on its own loopback port.Each migration followed the same rhythm: build, copy, write a systemd unit, add a tunnel ingress rule, flip the DNS record, delete the Azure resource. Once you’ve done it twice, it’s a template. And templates are exactly what an LLM agent is brilliant at applying — fast, consistently, and without getting bored on the fifteenth repetition.
Here’s the honest truth: the individual steps in a migration like this aren’t hard. They’re just numerous, repetitive, and unforgiving of small mistakes. A wrong port, a stale DNS record, a forgotten environment variable, a build that targets the wrong runtime — any one of them costs you twenty minutes of head-scratching, and there are hundreds of them across a dozen apps.
An LLM coding agent collapses that. I could say “migrate the next frontend the same way we did the last one,” and it would inspect the project, figure out the build, write the deploy server, wire up the service, and run the smoke tests — surfacing only the genuinely novel decisions for me to make. The work shifted from typing to deciding. I stayed in the architect’s seat; the agent did the plumbing.
It also caught and remembered the gotchas so I didn’t keep re-stepping on them — things like a static-host’s hostname binding silently blocking a DNS cutover until the old resource is deleted, or a dev-tool reverse proxy quietly dropping query strings, or an OAuth provider needing its redirect URI updated to the new hostname. Those are the kinds of papercuts that turn a clean afternoon into a frustrating week. Having them spotted, fixed, and noted as we went is what made the whole thing feel light.
This is the part that matters when you’re bootstrapping and every euro is runway.
On Azure I was paying for multiple App Service plans, a managed SQL database, storage, and assorted small line items — the kind of bill that’s “not that much” per service but very much something in aggregate, every single month, forever. Consolidating onto one VPS replaced most of that recurring spend with a single predictable monthly cost — and that one box has more CPU and RAM than the sum of the tiers it replaced. My side projects are faster now, not slower, because they’re not throttled by entry-level cloud SKUs.
Add in the free tiers around it — Cloudflare DNS, Tunnel, CDN, and SSL all cost nothing; R2 has no egress fees; SES is effectively free at my volume — and the math stops being close. It’s lopsided. I cut recurring cost meaningfully and got better performance. When you’re funding your own runway, that combination is rare enough to take seriously.
I’m not going to pretend this is free of trade-offs. The obvious one: it’s a single box. If it goes down, everything goes down together. On Azure, a problem with one service was contained to that service.
So I mitigate rather than ignore it:
systemd unit and every deploy is a scripted GitHub Action, standing the whole thing back up on a fresh box is a known, repeatable procedure — not an archaeology project.For a portfolio of side projects and an early-stage startup, “one well-backed-up box that I fully control” is a perfectly reasonable risk posture. I’m optimizing for cost, speed, and ownership while I find product-market fit — not for five-nines on day one. When a project earns the right to high availability, it can graduate to something more elaborate. Most never need to.
Put it together and the case writes itself:
The single-point-of-failure caveat is real, but it’s a managed risk, not a dealbreaker — and the snapshot-plus-backup safety net is cheap.
If you’ve got a graveyard of cloud resources quietly draining your runway, this is genuinely a great moment to reclaim it. The tooling — both the infrastructure side (tunnels, S3-compatible storage, managed DNS) and the AI side (a coding agent that can actually do the migration with you) — has never been this good. Big, scary, repetitive infra migrations have quietly become a thing one person can do in their spare time.
I took back control of my costs, my performance, and my stack. The portal’s empty now. It feels great.
Building in public while bootstrapping. If you’re weighing a similar move and want to compare notes, I’m around.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。