Earlier this year, I built a new home server and data storage system. From the hardware side of things, this was a whole new experience for me. But the software side also gave me a lot of opportunities to experiment.
My previous storage system was Synology, which is appliance-style software. The operating system is set up to be mostly foolproof, and additional software generally requires applications to be packaged specifically for Synology.
It is very convenient to have so many decisions made for you, and my original plan was to use TrueNAS as a replacement. Like Synology, TrueNAS has a web-based UI to manage the core services, and an app store to download additional software, all very connect-the-bricks. And if you can’t find an app you want, you can configure anything by using Docker.
The more I considered it, though, the more I realized that I didn’t want the limitations of being inside an opinionated system. When everything goes right with appliance-style software, it’s great. But if you veer too far away from the defaults, or if you run into problems, you find yourself fighting against the system instead of working with it.
Even Docker, which can make handling multiple services and dependencies both easier and more reliable, adds a level of complexity that can be a drag. Besides, I spend my time professionally running containerized, productionized services, writing config files that are used to generate other config files that eventually run and manage the services.
So instead, I decided to go bare metal, and I installed Debian. I have some experience with this from my Mini PC that I was using to complement the Synology. It is very common for software to have a Debian installer. And it isn’t too hard to write or change a systemd config file if you want to install something more obscure or customize things a little. I think you do need a better understanding of how the different parts of the system work together, but as a result, I feel like there is no magic, which means there is no limit to what I can do.
And then, mostly by chance, I stumbled into a Linux distribution called Void Linux. I was most intrigued by its service management system, which is called Runit, because instead of config files it has shell scripts. I don’t have anything in particular against systemd, but if my goal in going bare metal was to get rid of abstractions and config files, then this seemed like an even better fit for my hobby project.
One downside is that not as much software is packaged for Void compared to Debian. And I probably wouldn’t recommend Void to someone who isn’t comfortable with or willing to learn to write shell scripts. Also, setting up Runit services can involve a little bit of boilerplate, which some people (not me) are allergic to.
But if you clear those hurdles, the simplicity is your reward. The system boot
scripts are just shell scripts. Service definitions are just shell scripts that
are auto-restarted every time they terminate or fail. Instead of a complex
dependency management system, your service can just quit if something is
missing, and the next time it starts, maybe things will be in a better state.
Instead of writing a config file to create a custom /run directory or /tmp
directory, you can just put a mkdir inside the shell script. To enable or
disable a service, you put a symlink into the /var/service folder. To write
logs, you just print messages to stdout. And so on.
Anyway, that is the current state of my home server. It feels light and fun and unixy instead of cumbserome and enterprisey.