Note: This post is a draft
Having run an on-premise server for the past two years, I think my setup has finally matured enough to be worth talking about.
At any point, you can check out the source code for the server’s infrastructure here for a concrete example. For each service I talk about, I will also link the respective definitions in my config.
My minimalist mindset has unsurprisingly aided the architecture of my server. Throughout the rest of the post, you will come across the following broad strokes:
- Easy is not always simple
- Simple is better than easy
- There must be one (and exactly one) way of doing something
Hardware
The server is an old laptop which was on the verge becoming e-waste. Despite having a touchscreen display, the LCD had been battered into shards, making it no better than a shiny paperweight.
Although one could have kept the display, I carefully disassembled the machine to disconnect the corresponding ribbon cable because we are aiming for a headless setup. Removing the display also reduces the power draw.
Software
I have seen a lot of people grow monstrous fleets of docker containers in the name of “simplicity” and ease of use. Yet others take this further with dedicated operating systems like CasaOS to install containerized services in a single click.
Sure, these solutions might be easy but they are certainly not simple. Containers introduce the overhead of Linux kernel namespaces. This means accessing files on the host additionally requires creating a mount namespace.
To avoid all of that overhead, I opted for NixOS.
With NixOS, I can define the state of my system in a single configuration file, ensuring that the services are running close to bare metal without any abstractions. Most of the services require adding something along the lines of
services.myservicename.enable = true;
to the configuration file and issuing a system rebuild with the nixos-rebuild
command.
Storage Management
Initially, I had configured three different routes to transfer files to the server. Of these, only one service is in use today.
Syncthing
I had enabled Syncthing to automatically synchronize media from my phone. While it is a decent solution for a lot of use cases, it does not support partially sharing the contents of a directory. This annoying ‘all or nothing’ nature of Syncthing’s file sharing is what drove me away from it.
Samba
A lot of people recommended samba because of its support on almost all platforms. However, it turned out to be extremely slow. Yes, it boasts fancy video streaming capabilities but there are better solutions to building a media library than manually searching for a file like a caveman.
SSHFS (source)
SSHFS is the sneaky third option that made the win! It is often referred to as SFTP (Secure File Transfer Protocol)
but the filesystem is usually FUSE mounted as sshfs
.
The added advantage is that the connections go over SSH and uses the same credentials we would use to log into the server as our user.
SFTP is fast and available on almost all platforms:
- Linux: Native support
- Android: Native support on some devices. Alternatively, use Material Files
- Windows: Supported through WinSCP
- iOS: Suppported through Pisth
Freedom from the Botnet
Finally, we can talk about weeding out the proprietary services that are holding us back and replacing them with more privacy respecting alternatives.
Google Photos → Photoprism (source)
Since I backup my phone’s camera roll to the server, it’s often nice to have these photos and videos tagged and organized. Photoprism packs all the functionality of Google Photos including tagging people, pets and places in photos, as well as searching through them along the timeline.