-
Notifications
You must be signed in to change notification settings - Fork 0
Per Machine Config
NullOS is designed to manage multiple machines with shared configurations while allowing easy per-machine customization via a simple pipeline.
NullOS supports multiple machines using:
-
machines/{hostname}/default.nix: Per-machine variables and overrides. -
machines/{hostname}/secrets.yaml: Encrypted secrets via SOPS-nix. -
modules/system/hardware_{hostname}.nix: Hardware-specific configurations. -
machines/profiles/{profile}.nix: Shared feature flags for specific classes of machines (e.g.pcorserver).
Profile: pc
Hardware: Intel + NVIDIA (Prime) laptop.
- Uses NVIDIA PRIME (dGPU offload)
- Specialisation for
power-efficient(disables NVIDIA for battery life) - Passwordless sudo, Restic backups
Profile: pc
Hardware: Full NVIDIA (open driver) desktop.
- Full NVIDIA GPU active
- Steam enabled
- Configured as distributed build machine (speedFactor 2x) for other hosts.
Profile: server
Hardware: Small form factor headless server.
- Headless (
desktopEnvironment = null) - Minimal services
Boot the new machine with the NixOS installer and run:
nixos-generate-config --show-hardware-config > /tmp/hardware_newmachine.nixCopy /tmp/hardware_newmachine.nix to your NullOS repo as modules/system/hardware_newmachine.nix.
Create a folder for the new machine:
mkdir machines/newmachineCreate machines/newmachine/default.nix:
{
username = "yourusername";
hostname = "newmachine";
system = "x86_64-linux";
# Select desktop environment: "hyprland", "kde", or null
desktopEnvironment = "hyprland";
# Override any base feature flags
enableSteam = true;
# Extra arbitrary NixOS config (if needed)
boot.devSize = "8G";
}Create the secrets file for the new machine:
# Assuming your SOPS key is set up
sops machines/newmachine/secrets.yamlAdd required secrets like githubToken or resticRepository.
Also ensure you update .sops.yaml in the root of the project to allow the new machine if you use machine-specific keys, though currently NullOS uses a single user key.
Edit flake.nix and add the new configuration under nixosConfigurations:
nixosConfigurations = {
# Existing machines...
nslapt = mkSystem "nslapt" "pc";
nspc = mkSystem "nspc" "pc";
# Your new machine
newmachine = mkSystem "newmachine" "pc"; # Or "server" for a server profile
};sudo nixos-rebuild switch --flake .#newmachineThe core logic of NullOS per-machine configs lives in flake.nix lines 58-100.
-
Base defaults are loaded from
machines/profiles/base.nix. -
Profile overrides are applied from
machines/profiles/<profile>.nix(e.g. enabling Steam/Lutris for PCs, but disabling them for servers). -
Machine overrides from
machines/{hostname}/default.nixare applied last.
This resulting configuration object is named vars and is passed to all modules using specialArgs.
There's a neat quirk in NullOS: Any key inside machines/{hostname}/default.nix that is not one of the reserved variables (like username, enableSteam, etc.) is automatically bundled into extraNixosConfig.
This means you can place pure NixOS config directly inside your machine's default.nix without creating a whole new module.
Example:
{
hostname = "nsminipc";
# ... other vars ...
# This becomes part of the raw NixOS config:
services.periodic-reboot = {
enable = true;
timerConfig.OnCalendar = "weekly";
};
}Inside modules/software/packages.nix or home/default.nix, use vars to conditionally enable configurations:
{ config, pkgs, vars, lib, ... }:
{
config = lib.mkIf vars.enableSteam {
programs.steam.enable = true;
};
}This prevents you from needing complex if vars.hostname == "nspc" then ... statements. Instead, rely on the feature flags!
- Variables Reference - List of available feature flags.
- Managing Secrets - How to securely handle passwords.