This is my repository for storing and publishing the flakes that I've put together for my homelab. There are a few reasons that I've decided to go with NixOS as my operating system, which are mainly that:
- NixOS is Declarative: A declarative system (as opposed to an imperative system) is one where you declare your system state in a file (any .nix file in our case) instead of declaring it with commands. For instance, when I want to open a port in my firewall on a NixOS machine I just add a port number to the networking.firewall.allowedTCPPorts module in that machine's configuration.nix file.
- NixOS is Modular: Any given .nix file can be split up into different subfiles (as you can see in my modules folder) that can either be imported directly into other files or included as an import in a flake output (which is mostly what I do). This lets me organize my system configuration by different functions and, if I want to remove a program, its firewall port and its entire configuration, I can just remove the import without deleting the file that configures it. This is also how I can set up one common.nix file that has all the packages and settings that I want by default on all my machines and just import that file on all my flakes. This also lets me create reproducible Python and Javascript dev environments, though I won't go too much into how those work here.
- NixOS is Reproducible: Because NixOS is declarative and modular, you can take any new machine, install NixOS, git pull your configuration repository and have a completely functional work environment set up exactly the way you like it in less than five minutes. This is invaluable for me because I mainly use NixOS on Proxmox virtual machines, so being able to spin up a new VM in a few minutes is a huge benefit.
For anyone who hasn't tried NixOS, I really can't recommend it enough. Between the features I listed above and atomic rollbacks that allow you to revert to any previously working system configuration, NixOS got rid of all the struggles I've had with Linux and made running a complex homelab smooth and easy.
My homelab architecture basically runs on a server-client model, though it has a few twists that make it different. My machines are:
- Storage: This machine runs an NFS share that all of my other computers pull from. If I have anything that I want to be persistent, I put it on this share. It's also running PostgreSQL and a pgAdmin instance, which I use as the backend for all of my Podman containers.
- Pods: These machines (I have two of them right now) just exist to run Podman containers. I'm setting up secrets management with sops right now, but once I have I'm going to make a separate repository with all my compose.yml files and set up a Woodpecker CI pipeline that automates my deployment. These containers are set up to run under a user named Podrick (I couldn't resist) that isn't part of the wheel group. This ensures that any vulnerabilities in my containers can't expose sudo access. Setting that up has been a file and folder permissions headache, but it will be worth it once I start exposing some of these services to the public internet through a Cloudflare Tunnel.
- Raspberry Pi: This is a Raspberry Pi 4 Model B that I have set up as a backup for my Storage machine. It has an external HDD that is synced up to the storage machine's storage drive using Syncthing with a trash management system included. It runs on battery power, and I want to add in a systemd service that pings the storage machine every 5 seconds and switches the NFS mount on my Pods machines to my Raspberry Pi if my storage machine is down. It's also running PostgreSQL as a backup for the storage machine. This is also the only machine that isn't a Proxmox VM.
- Beast: This is my remote-builder machine. Right now it's just set up as a remote builder for my Raspberry Pi, but I'm going to set it up as a remote builder for my whole network using Colmena and a binary cache for my whole network to reduce the build load on my other machines. This is just because rebuilding your Nix system after you make a change to your configuration can be quite a RAM hog, so it's a good idea to have one powerful machine that handles the build for your other, lighter VMs.
Feel free to clone my repo and mess around with it! If you find anything that breaks in the process, let me know. While this isn't the simplest config around, I do think that it would be a pretty good place to start for someone who's running a lot of VMs and wants to begin using NixOS.