When My VPS Went Down: Migrating to Cloudflare Workers in a Panic
I’ll be honest, I didn’t plan to migrate my site to Cloudflare Workers today. My hand was forced.
I woke up to alerts telling me my VPS was down. My portfolio site, anthonyapierre.com, was completely unreachable. I’d been meaning to set up a proper failover for a while, but like most things that live on the “I’ll sort that eventually” list, it hadn’t happened yet.
This is the story of how, on the very first day my site went fully live, an unexpected outage turned into something genuinely useful.
The Setup Before
My site runs on Hugo — a static site generator. The built files were served by Nginx Proxy Manager running on an Eastern European VPS, which I pay around £8/month for. It’s a budget provider. The price is attractive, and up to today I had experienced maybe two instances of the service being down.
I’d never set up version control properly for the site either. Files lived on the VPS and nowhere else. Not ideal.
Step One: Get the Code to Safety
The first thing I did, even before thinking about failover. was push everything to GitHub. No point planning a recovery strategy if the files could disappear with the VPS. I had done this as part of my deployment stategy a few days ago, so I merely had to commit a few additional posts and some cosmetic changes, but the fact that the VPS was only sporadically up put some pressure on these actions.
Since the code wasn’t under proper version control day-to-day, this was a good forcing function. I now use GitHub Desktop for managing commits and pushes, which makes the whole process far more approachable than the command line for routine updates.
cd /opt/hugo-site
git add -A
git commit -m "pre-failover backup $(date '+%Y-%m-%d')"
git push origin master
277 files, 10.76 MiB — everything safely on GitHub within minutes.
The Migration: Cloudflare Workers
With the code safe, I turned my attention to the actual problem: getting the site back online independently of the VPS.
Cloudflare Workers turned out to be the right tool. Since Hugo generates a fully static site, there’s no server-side logic required — just files that need to be served globally. Workers handles this natively and the free tier is generous enough that a portfolio site will never come close to the limits.
The approach was to set up GitHub Actions to automatically build and deploy the site on every push. No more manual SSH sessions. No more VPS dependency for the site itself.
The GitHub Actions Workflow
I created .github/workflows/deploy.yml in the repository:
name: Deploy to Cloudflare Workers
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.146.0'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy
And a wrangler.toml in the root of the project:
name = "anthonyapierre-site"
compatibility_date = "2025-04-10"
[assets]
directory = "./public"
not_found_handling = "404-page"
Commit, push via GitHub Desktop, watch the Actions tab — the site was live on Cloudflare’s edge network within minutes.
DNS Switchover
The final step was updating the DNS in Cloudflare. I deleted the old A records pointing to the VPS IP and let Cloudflare Workers manage the custom domain directly. Within 30 seconds of the DNS update, anthonyapierre.com was back online.
The New Workflow
The real win from all of this isn’t just resilience — it’s the improved day-to-day workflow. Previously, updating the site meant SSH-ing into the VPS and running Hugo manually. Now it’s:
- Make changes to the markdown files
- Commit and push via GitHub Desktop
- GitHub Actions builds and deploys automatically
- Changes are live in under two minutes
That’s a proper CI/CD pipeline for a personal site, and it cost nothing to set up beyond an hour of work.
What I’d Do Differently
A few honest lessons from the day:
Version control everything from day one. Files that only exist on a single server are files waiting to be lost. GitHub (or any git host) should be the source of truth from the moment a project starts.
Don’t rely on a single point of failure for something client-facing. My VPS is fine for internal tools and self-hosted services, but a public portfolio site deserves better availability than a budget provider can reliably offer.
Static sites belong on edge networks. Hugo generates static HTML. Serving that from a single VPS in Romania when Cloudflare’s network spans 300+ cities globally was always the wrong architecture. The migration wasn’t just a fix — it was an overdue upgrade.
Set up CI/CD before you need it. The GitHub Actions workflow took about an hour to get right. That’s an hour I could have spent at any point in the past year rather than during an active outage.
Where Things Stand Now
The site now lives entirely on Cloudflare Workers. Every push to the master branch triggers an automatic build and deploy. The VPS still runs a few other services, but the portfolio is completely independent of it.
If the VPS goes down again — and with budget hosting, it probably will — the site stays up. That’s the outcome I wanted, and it took an outage to get me there.
Sometimes the forcing function is exactly what you need.