Self-deploying more of my own small web

a black and white photo of a swarm of pigeons mid-flight

I have recently started to move my personal code repositories away from GitHub, in favor of hosting them with a smaller, independent and collectively managed alternative - including for this static website. In the same spirit, I was also interested in whether I could be doing my small part to diversify my overall web hosting approach. Because, as nicely outlined in Any Technology Indistinguishable From Magic is Hiding Something by Jason, the cloud is not only just other people’s computers, but 3/4th of those computers are owned by Google, Amazon & Microsoft.

So, I wanted to get started with non-essential services that I could potentially self-deploy on some small hoster (i.e. I didn’t want to run my own mail server just yet). As a simple and affordable, pay-what-you-want hoster, I went with Uberspace, which provides a simple but well-equipped Linux shell to run your things on.

I decided to start off with FreshRSS[1] - which is an RSS reader that can be accessed from the web, but also through an API to tie in with my RSS-reader programs on my computers and phone - and a Wallabag, a read-later service to jot down things to read. And luckily, the collectively written experimental documentation of Uberspace helpfully provided instructions for easily setting up both tools!

At about the same time I also moved the code for my little PersonalAPI Django-app to Codeberg. As part of that move, I had to figure out how to get Woodpecker, the CI that Codeberg kindly provides, to automatically deploy any changes to Heroku - where the little Django-app lived so far. In the end, I managed to write a little CI script that used the Heroku API to push changes.

But that made me wonder: Instead of using Heroku, could I just get that Django-app to run on Uberspace too? Heroku was bought by Salesforce in 2010, and while for a while it used to be free for small hobby projects like my Personal API project, just using their smallest database by now costs a good bit of money. And remember how 75% of all “cloud” services are just Amazon, Google or Microsoft? Heroku is also just Amazon’s AWS with a fake mustache.

Just as for Wallabag and FreshRSS, the Uberspace Lab docs have a good starting point on how to get Django apps running on their infrastructure. I just made some minor tweaks to that, to re-use the pipenv-setup of the existing deployment to encapsulate the dependency/Python versions. But even with that, it was extremely quick and painless to get it up and running! It led to the next problem though: How to automate the deployment on the Uberspace?

The Uberspace lab docs didn’t provide a best pathway for CI deployments that weren’t just based on rsync-ing files over. But with some research I found webhook, which can provide a quite simple way to setup your own webhooks that can be triggered by sending GET or POST requests. It turned out to be quite easy to install even. In the spirit of giving back to the great lab-documentation, I’ve already made a successful PR to expand the documentation on a section on how to install webhook.

When triggered, my webhook for deploying the PersonalAPI fetches the latest version of the code from Codeberg, applies any potential database migrations, re-collects the static files and restarts the web-server for good measure. With that in place, I just needed to adapt the CI-script that is triggered on Codeberg to be good to go.

I’m really happy with that strung-together solution (and the other small bits of self-deployed solutions). First of all, it lets me take some more control over things, while learning a few new things in the process and hopefully also lessening the burden on others that kindly host publicly accessible tools. Secondly, it helps me to move away from the over-reliance on big-tech hosters. Instead of throwing too much money each month at Heroku/Salesforce/AWS (or some Software as a Service-provider), I’d much rather throw about the same amount of money at a small, independent hoster.


Links to the respective how-tos/configs:

My redeploy.sh simply consists of:

#!/bin/env bash

REPO="${HOME}/personal-api/"

git -C ${REPO} fetch && git -C ${REPO} rebase
cd ${REPO}
pipenv run ./manage.py migrate
pipenv run ./manage.py collectstatic --noinput

supervisorctl restart myapi

[1] I already switched to another free FreshRSS instance back when Feedly had started its union-busting services, but thought I could just as well deploy it myself.

Bastian Greshake Tzovaras

Bastian Greshake Tzovaras

Generally, things are better if you put open* in front of them.

orcid scholar rss facebook twitter github youtube mail spotify instagram linkedin flickr mastodon