I've transitioned between cloud services and self-hosting a few times:
1. Vercel Phase My first project used Vercel. Since my project was Next.js, the experience was decent. But as my project gained some users, I found that even for projects under 100 users, I needed to pay $20 per month. Since my service didn't require high performance, this cost felt steep.
2. Self-host Phase (Hetzner + Coolify) Later, I started setting up my own server with Hetzner and deploying with Coolify. Since Coolify is open-source and free, I only had to cover the cost of a VPS (even $5 a month was sufficient). I could deploy PostgreSQL instances and run a web server on it. But later I discovered that even this way, I still had to spend a lot of effort maintaining PostgreSQL and Redis. Even though they were containerized with Docker, managing them was still troublesome. I needed to pass various system and environment variables between services, which was very tedious.
3. Cloudflare Phase So later I switched to Cloudflare. With Cloudflare Workers, I can deploy fullstack applications and use D1 Database and Cloudflare KV to replace Redis. These features can be called directly within the Worker without needing to pass environment variables.
Plus, the local development experience is excellent and the pricing is very reasonable, so I've been using Cloudflare's entire suite ever since.
Yeah Cloudflare offering has become everything I wanted from AWS. So much simpler to deploy a basic full stack app + files. AWS has become considerably more difficult than self hosting.
I really wanted to like Cloudflare Workers and I'm sure there's good technical reasons but the way you need to use a Wrangler project to do things like enabling email felt too much like I was about to get locked into the platform.
It seemed like the bindings you needed to set to allow email can't actually be set (or even seen once Wrangler sets them) from the console at all.
> Even though they were containerized with Docker, managing them was still troublesome
Did docker make it easier?
The only issue I have with PostgreSQL is a bit of migration effort moving to new major versions.
> I needed to pass various system and environment variables between services, which was very tedious.
Was docker making this harder?
Went through a similar phase,
I think a mix of 2. and 3. is good for a small team or solo dev. Im throwing in a bit of homelab as well by adding some action runners and models on my desktop as well.
But cloudflare is great value for small teams. Not sure how it as at higher scale.
On the topic of env and config. It took me a while to get this write, and maybe overengineered.
But I invested a lot of time in trying to standardize env definitions, secrets manager, and per env config definition defined in my nx projects, and consumed by the commands or deployers. As well as pulumi for IaC.
I tried a couple of different approaches, but finally I just decided to use typescript as my config language. I use nx project.json but defined using typescript. And just define the env config as typescript functions to be injected to each command or deployment as a pure function of target env.