Shifting 1 VPS app stack to another - A Hostinger Story
moving-a-vps-without-losing-your-mind
I read on X/twitter that the Indian subscription of an American app, costs half the price. I live in India! I pay 10$ per year for Spotify - how didnt i realise this for my VPS provider (rhetorical)! So I decided to move my hostinger US based account, to an Indian account (Hostinger was not present in India when I set up my account in 2021).
The first thing I did before touching a single container was call support and ask whether the price difference was actually about the datacenter, or just which account was footing the bill. Turns out half of these "migrations" people put themselves through are not migrations at all, they're a billing conversation wearing a lab coat. Mine, unfortunately, was the real thing, so no such luck.
Here is what nobody tells you about moving a Docker Compose stack from one VPS to another: the actual copying of files is the easy part. Any fool who knows how to copy-paste on a GUI, can do it. The hard part is the emotional labour of not touching the old server until you are absolutely, embarrassingly, triple-certain the new one works, because the old server is the only thing standing between you and tons of blood, tears, memories.... and Secrets!
So I did the boring thing first. I asked Kodee to give me a download of my VPS - the no secrets version. Kodee is amazing!
New server, new SSH key, password auth disabled before I let myself get comfortable, because there is a special kind of person who migrates an entire production stack and then leaves root/root as a valid login, and I did not want to become that person on a Saturday. Docker, Compose, UFW, Fail2Ban, all installed fresh, mirroring the old server's rules port for port. Then I recreated the folder structure, one directory per stack, same as the source, because consistency here is not aesthetics, it's just future-me doing a favour for present-me.
The actual data move is where the checklist earns its keep. Reverse proxy config gets tar'd and scp'd over, minus the certificate store, because if you're using Let's Encrypt there is genuinely no reason to drag old certs across, they reissue themselves the moment DNS points the right way and copying stale ones is asking for a debugging session you didn't need to have. Every app with a database gets the same three-step ritual: dump it, ship it, copy the volume separately. It is repetitive in the way that flossing is repetitive, unglamorous but the alternative is worse.
And then, the part I actually enjoy: bringing everything up on the new server while the old one is still alive and serving traffic, previewing the whole thing through a hosts file edit before DNS has any idea a change is coming. You visit your own domain, get a rude SSL warning because the cert hasn't been issued for this IP yet, click through it like a responsible adult, and just look. Does Nextcloud log in. Does the blog render. Does the thing you built actually survive being picked up and put down somewhere else, which is a fairly reasonable thing to ask of any piece of infrastructure (or honestly, of most people).

Here's the bit I didn't expect going in, and it's the actual lesson, not a footnote: the migration itself is not the risky part, the DNS cutover is, and everyone's instinct is to rush that step because it feels like the finish line. It isn't. Dropping your TTL 48 hours ahead and doing one final delta sync right before flipping the A record is the difference between a clean cutover and explaining to yourself at 2am why half your users are hitting a database that's a day out of date.
I kept the old server running for a week after everything went green, untouched, like a spare parachute you hope you never need. Cancelled it only once I'd stopped flinching every time I opened docker compose logs -f.
Would I do it again for a marginally cheaper plan? Probably not. Would I do it again because I now trust my own backups more than I trust any single server humming away in a datacenter I'll never see? Absolutely, and that, more than the money, was the actual point all along.