Skip to main content

Overview

NixOS system configurations define the operating system settings for physical machines, virtual machines, and containers in your homelab. Each system configuration is stored in the systems/ directory.

System Structure

Each system has its own directory under systems/ containing:
  • default.nix - Main system configuration
  • meta.json - System architecture metadata
  • disko.nix - Disk partitioning configuration (optional)
  • facter.json - Hardware detection report (optional)
  • secrets.yaml - SOPS-encrypted secrets (optional)

Directory Layout

systems/
├── lg-laptop/
│   ├── default.nix
│   ├── meta.json
│   ├── disko.nix
│   ├── facter.json
│   └── secrets.yaml
├── zephyrus/
│   ├── default.nix
│   ├── meta.json
│   └── ...
└── moonlight/
    └── ...

System Architecture (meta.json)

Every system must have a meta.json file that specifies the target architecture:
meta.json
{"system": "x86_64-linux"}
system
string
required
The NixOS system architecture. Common values:
  • x86_64-linux - 64-bit Intel/AMD
  • aarch64-linux - ARM 64-bit
  • i686-linux - 32-bit Intel/AMD

Basic System Configuration

Here’s a minimal system configuration:
systems/example/default.nix
{pkgs, ...}: {
  core = {
    boot.enable = true;
    
    networking = {
      network-manager.enable = true;
    };
    
    users = {
      username = {
        hashedPassword = "$y$...";
        admin = true;
        shell = pkgs.fish;
        publicKey = "ssh-ed25519 AAAA...";
      };
    };
  };
}

Complete System Examples

A complete configuration for a desktop laptop with KDE Plasma:
systems/lg-laptop/default.nix
{pkgs, ...}: {
  imports = [
    ./disko.nix
  ];

  core = {
    nixconf.determinate-nix.enable = true;

    boot = {
      enable = true;
      plymouth.enable = true;
    };

    hardware = {
      enable = true;
      reportPath = ./facter.json;

      gpu = {
        integrated.intel = {
          enable = true;
          deviceId = "a7a0";
        };
      };

      hid = {
        tablet.enable = true;
        xbox_controllers.enable = true;
      };

      bluetooth.enable = true;
    };

    gitops = {
      enable = true;
      repo = "https://github.com/soriphoono/homelab.git";
      name = "lg-laptop";
    };

    secrets = {
      enable = true;
      defaultSopsFile = ./secrets.yaml;
    };

    networking = {
      network-manager.enable = true;
      tailscale.enable = true;
    };

    users = {
      spookyskelly = {
        hashedPassword = "$y$j9T$...";
        admin = true;
        shell = pkgs.fish;
        publicKey = "ssh-ed25519 AAAA...";
      };
    };

    clamav.enable = true;
  };

  desktop = {
    environments.kde.enable = true;
    features = {
      printing.enable = true;
      gaming.enable = true;
    };
  };
}

Configuration Modules

Core Module

The core namespace contains essential system configuration:
core.boot.enable
boolean
default:"false"
Enable bootloader configuration
core.boot.plymouth.enable
boolean
default:"false"
Enable Plymouth boot splash screen
core.hardware.enable
boolean
default:"false"
Enable hardware support and detection
core.hardware.reportPath
path
Path to facter.json hardware report for automatic configuration
core.networking.network-manager.enable
boolean
default:"false"
Enable NetworkManager for desktop systems
core.networking.openssh.enable
boolean
default:"false"
Enable OpenSSH server
core.networking.tailscale.enable
boolean
default:"false"
Enable Tailscale VPN
core.gitops.enable
boolean
default:"false"
Enable automatic GitOps updates
core.gitops.repo
string
Git repository URL for GitOps
core.gitops.name
string
System name in the repository
core.secrets.enable
boolean
default:"false"
Enable SOPS secrets management
core.secrets.defaultSopsFile
path
Default SOPS secrets file

Desktop Module

The desktop namespace configures desktop environments:
desktop.environments.kde.enable
boolean
default:"false"
Enable KDE Plasma desktop
desktop.environments.cosmic.enable
boolean
default:"false"
Enable COSMIC desktop
desktop.features.gaming.enable
boolean
default:"false"
Enable gaming support (Steam, Lutris, etc.)
desktop.features.printing.enable
boolean
default:"false"
Enable CUPS printing support
desktop.features.virtualisation.enable
boolean
default:"false"
Enable virtualization (QEMU, libvirt, etc.)
desktop.services.asusd.enable
boolean
default:"false"
Enable ASUS laptop support (ROG laptops)

Hosting Module

hosting.single-node.enable
boolean
default:"false"
Enable single-node hosting services (Docker, Traefik, etc.)
hosting.clustering.enable
boolean
default:"false"
Enable Kubernetes clustering support

User Configuration

Users are defined in the core.users attribute set:
core.users = {
  username = {
    hashedPassword = "$6$...";
    admin = true;
    shell = pkgs.fish;
    publicKey = "ssh-ed25519 AAAA...";
    extraGroups = ["docker" "libvirt"];
  };
};
core.users.<name>.hashedPassword
string
required
Password hash generated with mkpasswd
core.users.<name>.admin
boolean
default:"false"
Grant sudo/wheel access
core.users.<name>.shell
package
default:"pkgs.bash"
User’s default shell
core.users.<name>.publicKey
string
SSH public key for authentication
core.users.<name>.extraGroups
list
Additional groups for the user

Hardware Configuration

GPU Support

core.hardware.gpu.integrated.intel = {
  enable = true;
  deviceId = "a7a0";
};

Input Devices

core.hardware.hid = {
  tablet.enable = true;              # Wacom/drawing tablets
  xbox_controllers.enable = true;    # Xbox controllers
  logitech.enable = true;            # Logitech devices
  qmk_keyboards.enable = true;       # QMK keyboards
};

Other Hardware

core.hardware = {
  bluetooth.enable = true;  # Bluetooth support
  adb.enable = true;        # Android Debug Bridge
};

Importing Additional Files

You can split configurations across multiple files:
systems/example/default.nix
{pkgs, ...}: {
  imports = [
    ./disko.nix
    ./hardware.nix
    ./networking.nix
  ];

  # Main configuration
  core = {
    # ...
  };
}

Using Custom Modules

Import custom modules from the modules/nixos/ directory:
# Custom module is automatically available
core.hardware.enable = true;
desktop.environments.kde.enable = true;
hosting.single-node.enable = true;
All modules in modules/nixos/ are automatically imported. See the Modules documentation for details.

Next Steps

Home Manager

Configure user environments and applications

Modules

Learn about available modules

Secrets

Manage sensitive data with SOPS

GitOps

Enable automatic updates

Build docs developers (and LLMs) love