Flake for my personal desktop and self-hosted services.
Attempting to view the Flake and its nixos hosts as a single logical unit, rather than trying to manage a collection of multiple computers.
- Homelab/selfhosting focus with multiple docker and nixos container modules for various servers and services.
- Programmatically configured Dashboard that automatically expands as new hosts are added to the flake. Dashboard monitors host status, the current Nix Flake revision installed on each system, and the current revision on Gitlab.
- Programmatically configured uptime monitoring with Gatus, no matter which host a new service is deployed on, the Gatus server will automatically update its configuration to include the new service - Homepage dashboard also does the same with links to all current services automatically.
- Programmatically configured notifications and monitoring for failed Nixos updates and zfs backups, server and service downtime etc with Ntfy and Gatus.
- Tailscale modules for general VPN access, initrd ssh access, docker and nixos container configuration etc.
- All Flake host networking is heavily reliant on Tailscale, meaning automatic HTTPS certificates for all services, automatic DNS records, controlled Zero Trust access between all devices, no open ports required on any device. Additionally, no reliance on LAN for networking, so I can move any server to any network without any additional configuration required. Tailscale ACL is configured with Pulumi here.
- The installation of NixOS is made convenient and consistent through declarative partitioning of disks, and a single install ssh command.
- Github Actions automatically updates the flake.lock weekly and run basic checks on the updates.
- All NixOS systems are set to automatically check for updates every hour, keeping all hosts in sync and identical as possible.
- Ensures a clean system on every reboot by wiping root (rolling back an empty zfs snapshot), while preserving specified files across reboots.
- The files that are designated to persist are all stored in a single location, enabling automated backups that only include important files.
- Backup server which automatically schedules new backup tasks as additional hosts are added to the flake by default.
- The flake manages the entire system, including secrets.
- (New in-progress) A single
inventory.nixfile where all non-hardware device specific configuration happens. This is useful for clarity and readibility, but more importantly it allows all hosts to be "aware" of all other hosts and their configurations. - All custom modules are joined together into a couple of Flake outputs, which are then ALL imported into the host in bulk.
- Custom modules all have options and are disabled by default. They must be enabled with
config.yomaq.moduleName.enable = true - Host modules (in /modules/hosts) that Nixos and Darwin can share are kept as identical as possible. Module options are shared between them in a
default.nixfile, while config implementations that differ will be innixos.nixordarwin.nixrespectively. - All modules are automatically imported into their Flake Outputs without the need to manually list them all. You can simply drop in a new file in /modules/hosts or /modules/home-manager etc, and it will be automatically imported into the correct Flake Output.
- User accounts, similar to host modules, are configured with
darwin.nixandnixos.nixfiles to keep configuration as consistent as possible (for all non home-manager user config). - User specific config is kept clean and easy to read in the
/usersdirectory and are included on a system withconfig.yomaq.users.enableUsers = [ list of users ];
Using the git revision of the flake, you can easily see which hosts are out of date.
Build on NixOS
Install a host that already has configuration:
- boot the host into a nixos installer (installer-iso ouput will build a nixos installer iso that is pre-loaded with a tailscale key to auto join the installer to your tailnet for easy remote installations), and set the root password (already set for installer-iso).
- complete the following steps on a different x86_64 machine with nix installed
nix developto enter the dev shell from within the git directoryyo-install-encrypted $hostname $ipaddress- enter ssh password
- restart host & unlock luks
yo-keygen $ipaddress- update inventory with the new hostkeys then rebuild once
yo-rbrl-ip $hostname $ipaddress
Configure new host:
- boot up installer-iso on the host
- complete the following steps on a different x86_64 machine with nix installed
- duplicate existing host folder in
/hosts - update hostname & disk configuration, checking
/modules/hosts/zfs/disks/for full disk config options - run
nix develop&yo-info $ipaddress - update hostID, ethernet drivers, and disk name with the output of
yo-info - when running the install as shown above it will automatically update the
hardware-config.nixfile for the new machine.
NixDarwin (MacOS) Setup
Install Nix on MacOS:
curl -sSf -L https://install.lix.systems/lix | sh -s -- install
Install Homebrew: https://docs.brew.sh/Installation
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Build Darwin for the first time (replace midnight with the correct hostname)
nix run nix-darwin -- switch --flake github:yomaq/nix-config#midnight
Repeat the following to update
darwin-rebuild switch --flake github:yomaq/nix-config
ToDo
- Add a self hosted nix store cache server.
- Move to flake-parts, if it does what I understand it does then everything will become a lot more streamlined and readable.
- Microvms, migrate some nixos-containers to microvms, mostly because nixos-containers increase build times.
- Smoothout tailscale-initrd, it works, but it needs some tweaks.