Running a blog without American tech
When AWS goes down, the world goes down. In combination with Azure and Google Cloud, over 60% of cloud infrastructure is run by just 3 companies[1]. A whooping 20% of all web traffic runs through Cloudflare, which is used by 35% of Fortune 500 companies[2]. In 2021, 44% of respondents to a survey conducted by JetBrains reported using GitHub at their company[3]. Due to these services being so big and so ubiquitous, they are very easy to use. Vercel will handle almost all the tricky parts of deployment for you, especially if you connect to GitHub, Gitlab, or Bitbucket (there is no option or instructions to connect to a repository outside of those three). The diverse nature of the web begins to crumble if it is all contained in a few places. When I began thinking about this transition, I wondered if there were any comparable alternatives to Cloudflare at all; some things are only achievable at scale.
My motivation for this post is to show that it is possible to run a blog in 2025 without using any big tech services, to lay out how I did it, and to give some brief broad lessons learned from the process. There have always been websites hosted from individuals’ homes, a raspberry pi, even on a server run off of solar energy. This post is geared more towards those that are currently using something like Vercel, and are unsure if there are any other strategies to go from code to deployment that are feasible for someone without heavy system administrator experience.
Components and transitions
- Code Repository: GitHub -> Codeberg
- Deployment: Vercel -> Bash Script
- Web Server: Vercel -> Caddy
- CDN: Cloudflare -> Bunny
The pipeline before this transition was:
- Write the blog in eleventy
- Push to GitHub on a non-main branch, create a Pull Request, review the preview site generated by Vercel
- Merge to main
- See site live on www.markpitblado.me
This system had a few benefits. I didn’t need to think of uptime or server maintenance at all, as Vercel took care of that. Vercel also tested deployments before bumping them to production, and allowed for rollbacks at anytime. All pull requests would also get tested to see if their deployment was successful before merging into main.
The first thing that I transitioned was the code repository, from GitHub to Codeberg. I won’t write much about this transition because both services function very similarly, and there is even a tool to migrate over. After the transition, to keep the deployment process to Vercel similar, I used a simple CI pipeline that utilized the vercel cli command. This worked fine, so fine in fact, that I never really learned must about hosting a static site. It all just worked.
The next step was moving away from Vercel. The biggest barrier to this was finding a cheap VPS. I didn’t want to be paying $10 a month just to run a static website. I explored Fullhost, a Canadian hosting company, but the cheapest VPS didn’t meet the budget[4]. Infomaniak, a Swiss company, does have a VPS Lite offering for 3 euros per month, and I ended up there. The tooling is comparable to a provider like DigitalOcean, though slightly less refined (like I said in the intro, there is a reason why the tech giants are the favourites). It does offer security key support, which I did appreciate.
Setting up a simple static webserver
Setting up a server can be tricky if you haven’t done so before. For initial server setup on Debian or Ubuntu, I would recommend this article. To host a website, you just need a single user, and have ports 80 and 443 open to the world. Many providers (including Infomaniak) allow you to configure a firewall through the interface, however you can use ufw if you prefer. I would recommend only allowing connections to ssh from your specific IP address to increase security if you are able, in addition to the other hardening steps.
The first (and really only) thing you need to do is get a built copy of your website onto the server. Most static site generators should have guidance on how to do this, for a node js based site it would be something similar to npm build
. For Jekyll it would be something like bundle exec jekyll build
. To copy over your files to the new server, you are going to need to run either scp or rsync. I’ll showcase an example using scp
below. Note you may use the IP address of the server instead of example.com
if you prefer.
scp -i /path/to/ssh_key -r ./_site user@example.com:/path/to/directory
You can automate that process by creating a deploy.sh script. Now, I have a script (ignored by git) that builds the site and sends it to the server. If you want to go even further, you could also do it through a CI pipeline. The script builds then ships the site to the server to be served.
npm run build
rsync -avz --delete --progress ./_site/ user@server.example.com:/var/www/website
Next, I would recommend Caddy as a simple web server that will serve the static files. For a guide on static file hosting, check out the caddy documentation. You can either use the command line command, or a caddy file. Assuming all went well, you should see your site live!
What is a CDN, and what is it good for?
A Content Delivery Network (CDN) allows you to serve your website faster around the world by creating Points of Presence (PoPs) that cache your content. However, the biggest benefit that I was looking for was the ability to reduce the load on the little web server, and to protect it a bit against bots. Cloudflare offers a web application firewall (WAF) and DDoS protection that is the best in the business, and the only other company that I knew in the space was Fastly[5]. Just in time for this post, Bunny CDN launched a new shield product which does compare to Cloudflare’s offerings in many ways. Since I already used them for images, it made sense to try to bundle things together. I opted to go all in and transfer the DNS in as well, and this makes deploying a CDN in front of services even easier.
Creating a CDN for a site on a root domain can be tricky. The way that was recommended by Vercel was to redirect the root domain (example.com
) to www.example.com
. Performing this redirection in Caddy is simple:
example.com {
redir https://www.{host}{uri}
}
www.example.com {
<stuff for static site here>
}
But, if you put a CDN in front of both, an infinite redirect will occur. Therefore, as far as I can tell, the best practice is to just place the CDN in front of the www.example.com
path. Using web-check.xyz on apple.com
and www.apple.com
this seems to be how they have it setup also. The first will ping a server in California owned by Apple, while the latter will ping Akamei, their CDN provider[6].
Another important note specifically with Caddy and Bunny, do not click force ssl in Bunny as this will interfere with Caddy certificates. See this forum discussion post for more details. I did not have any errors when proxying through Cloudflare, however I believe this was because the Cloudflare settings were set to use the origin certificate (what they refer to as strict).
Cost comparison
Big companies have generous free tools because they can afford to do so. Your usage is subsidized by the massive companies paying enterprise rates. A free tier, however, is never a guarantee, and once companies capture the market completely they usually eliminate these free tiers; sometimes known as embrace, extend, extinguish. With a setup like the one described here, you would be paying 3 euros per month for the server, and likely $1 for the CDN (the minimum charge). Donations to Codeberg are optional, but would help keep the service running.
Speed comparison
The speed is similar behind the CDN, however there is a noticeable lag in accessing the origin servers (as they are now located in Switzerland). I could have alleviated this by going with a Canadian provider for the servers.
Conclusion
In moving to services that do less of the heavy lifting, there are definitely moments where you will feel “wow this is easier on bigger services”. Yet, I also enjoyed learning more about hosting static sites through this process, something that would not have happened if I always had Vercel do everything for me. Now I can even play with things like load balancing or server monitoring, not because I need to, but because learning is fun. The side effect is supporting a marketplace that is more diverse and less focused on a few major players.
https://www.statista.com/chart/18819/worldwide-market-share-of-leading-cloud-infrastructure-service-providers/ ↩︎
https://www.nasdaq.com/press-release/cloudflare-named-fortune-future-50-company-ranked-14-2024-list-2024-12-04 ↩︎
https://www.jetbrains.com/lp/devecosystem-2021/team-tools/ ↩︎
I am exploring them as a registrar though, especially for
.ca
domains. ↩︎I have heard many positive things about Fastly, and they contribute quite a bit back to the open source community. ↩︎
If anyone has any more information or insights about this, I would love to hear about it ↩︎
- ← Previous
The joys of buying music - Next →
Nordhold is a fresh take on tower defense