Skip to main content
This guide walks you through adding a new NixOS system to your homelab infrastructure.

Prerequisites

  • A running NixOS installation or target machine
  • SSH access to the target system
  • Your SSH public key for authentication
  • System hostname decided

Creating a New System

1

Create Issue First

Following the Issue-First policy, create a GitHub issue describing the new system:
# Example issue title:
# "feat: add production-server system configuration"
Include details about:
  • System purpose (desktop, server, container)
  • Hardware specifications
  • Required modules and features
2

Create Feature Branch

Create a short-lived branch from main:
git checkout -b dev-add-production-server
3

Create System Directory

Create a new directory under systems/ with your system hostname:
mkdir -p systems/production-server
cd systems/production-server
4

Create System Configuration

Create a default.nix file with your system configuration:
systems/production-server/default.nix
{
  pkgs,
  modulesPath,
  ...
}: {
  imports = [
    (modulesPath + "/virtualisation/proxmox-lxc.nix")
  ];

  core = {
    gitops = {
      enable = true;
      repo = "https://github.com/yourusername/homelab.git";
      name = "production-server";
    };

    networking = {
      lxc.enable = true;
      tailscale.enable = true;
    };

    users = {
      yourusername = {
        hashedPassword = "$6$...";
        admin = true;
        shell = pkgs.fish;
        extraGroups = ["input"];
        publicKey = "ssh-ed25519 AAAA...";
      };
    };
  };

  # Enable required features
  hosting.single-node.enable = true;
}
5

Add Disk Configuration (Optional)

If using disko for disk management, create a disko.nix file:
touch systems/production-server/disko.nix
Configure your disk layout according to your needs.
6

Register System in Flake

Add your system to the flake outputs in flake.nix:
nixosConfigurations = {
  # ... existing systems
  production-server = nixpkgs.lib.nixosSystem {
    system = "x86_64-linux";
    modules = [
      ./systems/production-server
    ];
  };
};
7

Validate Configuration

Run flake checks to ensure your configuration is valid:
nix flake check
The pre-commit hooks should handle this automatically, but manual validation ensures everything compiles correctly.
8

Commit Changes

Commit your changes using conventional commits:
git add systems/production-server/
git commit -m "feat: add production-server system configuration"
9

Deploy System

Deploy the configuration to your target system:
nixos-rebuild switch --flake .#production-server --target-host root@production-server

System Types

Desktop systems typically include:
desktop = {
  environments.kde.enable = true;
  features = {
    gaming.enable = true;
    virtualisation.enable = true;
  };
};

core.hardware = {
  bluetooth.enable = true;
  gpu.dedicated.nvidia.enable = true;
};
Server systems typically include:
hosting.single-node.enable = true;

core.networking = {
  openssh.enable = true;
  tailscale.enable = true;
};
Container systems use:
imports = [
  (modulesPath + "/virtualisation/proxmox-lxc.nix")
];

core.networking.lxc.enable = true;

Common Configuration Options

Users

Define users with their configuration:
core.users = {
  username = {
    hashedPassword = "...";
    admin = true;  # Adds to wheel group
    shell = pkgs.fish;
    extraGroups = ["docker" "input"];
    publicKey = "ssh-ed25519 ...";
  };
};

Networking

Enable networking modules:
core.networking = {
  openssh.enable = true;
  tailscale.enable = true;
  network-manager.enable = true;  # For desktops
};

Hardware

Enable hardware support:
core.hardware = {
  bluetooth.enable = true;
  gpu.dedicated.nvidia.enable = true;
  hid.logitech.enable = true;
};

Next Steps

Build docs developers (and LLMs) love