Home Posts Links Notes Now

Software I like to self-host


I self-host many apps and I’ve realised that the ones I like the most all share these features:

My goal is to have an app that can be deployed anywhere trivially and that requires very low ongoing maintenance. Self-hosted apps typically have a very small number of users (often just one!) and sit idle most of the time. Ease of operation is more important than other concerns like scalability or even high availability.

Single binary

When I stand up a service, my ideal workflow is to obtain the application binary, run it and be done with it. No dependencies to install, no Docker images with half an operating system in it. Just a binary. Once I’m happy with the app I configure a systemd service and that’s it.

These days I use Nix and almost always I can find a module for the services I want. The bring up process is pretty much just adding a few lines to the config file regardless of how the program is written. Still, if I have to write my own module, I know what kind of applications I’d rather package up.

Single process

When designing for scalability splitting a service in many microservices that can be operated independently makes sense. The apps I self-host have almost no load and splitting them up is just going to give me more work: more things to configure and to keep running.

Fully configurable programmatically

I like infrastructure as code. I want to configure everything once and for all in a configuration file. Sure clicky UI are good for discovering features and for playing around with the service but once that phase is over I find having all the configuration safely stored in a version control system much more valuable.

Uses SQLite

Services need a place where to store their data. With little load and an operator not keen on having more dependencies than strictly necessary to maintain SQLite is a very good choice. This way each app has its own completely independent database with close to zero operational cost. As much as I like Postgres I'm going to reach for it only for applications that actually need it.

Protip: remember to back all these databases up. sqlite3 db.sqlite ".timeout 10000 .backup backup.sqlite" does the job. I then use Restic to safely store the backups remotely.

Frugal with resources

For a very long time I self-hosted services on a very old Raspberry Pi so I didn’t have lots of resources to play with. Now I have a mini PC but I still like to keep it with as little load as possible. When services are frugal with resources I can just run more of them on the same hardware and I can have very good performance even on old machines.

When choosing which services to host I tend to prefer software written in Rust or Go as they typically they offer great performance and low resource usage.

Thanks for reading. Feel free to reach out for any comment or question.