Switching from Netlify to Uberspace
TL;DR: Some rough notes on how I switched hosting this website from Netlify to Uberspace, and analytics from Plausible to Goatcounter.
Background §
I have been hosting this website with Netlify since January 2018, which has in general been a great experience! It was easy, convenient and free to host a static website. While some features were quite useful (e.g. branches automatically creating website previews on hidden subdomains), in general Netlify was far more featureful than I needed (e.g. severless functions, team management).
Strangely, the one Netlify feature I actually paid for did not feel worthwhile: Netlify Analytics. It had some major pain points, but I stuck with it for… a while: almost 4 years in total (August 2019 until July 2023). Most vexing was that it stored only the past 30 days of data, so was useless for spotting any long-term trends. As a workaround, I used Python to download data from the undocumented API, and created my own long-term chart in a local spreadsheet. However, Netlify Analytics was still limited in other ways, such as only showing the top 201 most viewed pages. So, in July 2023 I switched from Netlify Analytics to Plausible. Plausible was easy to set up, and solved all the problems I had with Netlify Analytics.
I’ve always liked the idea of self-hosting, which is not possible with Netlify. I’ve also had a background concern about Netlify since this incident where a customer was sent a huge bill. Earlier this year I briefly dabbled with using Coolify as a self-hosted alternative to Netlify. My original plan was to host this website on a Raspherry Pi at home, but that comes with some trade-offs2.
Recently, I came across Uberspace which looked like a good middle-ground: affordable hosting for “people who want to look behind the scenes […] and generally prefer working with a text-based console”. However, while Uberspace is affordable, it is not free. I did not want to be paying for two subscriptions (Uberspace + Plausible), so looked into self-hosted analytics alternatives and found Goatcounter.
So, we arrive at the conclusion: I decided to switch my hosting from Netlify to Uberspace, and also switch my analytics from Plausible to Goatcounter. Here is how.
Remote access §
SSH §
Followed this guide to set up SSH access.
Configure domain §
Add domains to Uberspace §
Your Uberspace website is managed through a CLI tool called uberspace
.
Use uberspace
to add the web domains:
uberspace web domain add smhk.net
uberspace web domain add www.smhk.net
Each of these commands took ~15 seconds to run.
Upon completion, they print out the IPv4 and IPv6 addresses for the A
and AAAA
records respectively.
Configure DNS §
Previously I was using Netlify for DNS. However, since I am migrating from Netlify to Uberspace, I need to find a different DNS provider.
My domain name is registed through Mythic Beasts, who were delegating the DNS to Netlify. I will switch to Mythic Beasts for DNS.
In the Mythic Beasts dashboard I enabled DNS, then added A
and AAAA
records for @
and www
respectively.
Redirecting www to non-www domain §
I have registed both smhk.net
and www.smhk.net
with the uberspace
tool. I want www.smhk.net
to redirect to smhk.net
.
Create an .htaccess
in the DocumentRoot:
$ nano /var/www/virtual/smhk/html/.htaccess
Populate with this:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
Build website §
Hugo §
The website is built with Hugo.
Followed this guide to set up Hugo on Uberspace.
I used this version of Hugo:
wget https://github.com/gohugoio/hugo/releases/download/v0.136.5/hugo_0.136.5_linux-amd64.tar.gz
This website’s source is stored in Git, which comes pre-installed in Uberspace. As the guide suggsts, I used the directory ~/hugo_websites
for storing a local copy of the website source:
cd ~/hugo_websites
git clone <URL>
However, I deviated from the guide for the publish location. If you only want to publish one website, then /var/www/virtual/<USER>/html
is the way to go. However, if you wish to publish multiple websites under the same <USER>
, then replace /html
with /<URL>
for each site, e.g. /var/www/virtual/<USER>/smhk.net
As suggested here, to use the same domain for multiple sites you can use a softlink. For example, to have www.smhk.net
use the site at smhk.net
:
$ cd /var/www/virtual/<USER>/
$ ls
html
$ mkdir smhk.net
$ ln -s smhk.net www.smhk.net
$ ls
html smhk.net www.smhk.net
$ mv html/* smhk.net/
NodeJS §
This website is also built with NodeJS.
NodeJS is pre-installed to Uberspace (see this guide).
$ # List the installed versions of NodeJS
$ uberspace tools version list node
- 18
- 20
$ # Choose a version to use
$ uberspace tools version use node 20
Selected Node.js version 20
The new configuration is adapted immediately. Minor updates will be applied automatically.
$ # Check the chosen version
$ uberspace tools version show node
Using 'Node.js' version: '20'
Building §
Can now run the build command:
npm install
npm run build:smhk
Analytics §
Goatcounter §
Instead of Plausible, this website will switch to Goatcounter.
Followed this guide to set up Goatcounter.
Add goatcounter
subdomain:
uberspace web domain add goatcounter.smhk.net
Add web backend on port 1235
:
$ uberspace web backend set goatcounter.smhk.net/ --http --port 1235
Set backend for goatcounter.smhk.net/ to port 1235; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
$ uberspace web backend list
goatcounter.smhk.net/ http:1235 => NOT OK, no service
/ apache (default)
Add goatcounter
to Mythic Beasts DNS.
Set up the service:
$ nano ~/etc/services.d/goatcounter-smhk.ini
$ supervisorctl reread
goatcounter: available
$ supervisorctl update
goatcounter: added process group
$ supervisorctl status
goatcounter RUNNING pid 9097, uptime 0:00:06
[program:goatcounter-smhk]
command = %(ENV_HOME)s/goatcounter/smhk.net/goatcounter serve -listen :1235 -tls http -db sqlite+%(ENV_HOME)s/goatcounter/smhk.net/db/goatcounter.sqlite3
autostart = true
autorestart = true
# `startsecs` is set by Uberspace monitoring team, to prevent a broken service from looping
startsecs=30
Summary §
These notes covered how I updated this website to switch:
- Hosting from Netlify to Uberspace.
- Analytics from Plausible to Goatcounter.
- DNS from Netlify to Mythic Beasts.
It was quite straightforward thanks to the great Uberspace documentation: