NixOS Essentials

System Rebuild

sudo nixos-rebuild switch              # Build and activate immediately
sudo nixos-rebuild test                # Activate without adding boot entry
sudo nixos-rebuild boot                # Add boot entry, activate on next reboot
sudo nixos-rebuild build               # Build only, don't activate
sudo nixos-rebuild switch --flake .#hostname  # Flake-based rebuild
sudo nixos-rebuild switch --upgrade    # Update channels first, then rebuild

Configuration Basics

Default config location: /etc/nixos/configuration.nix

{ config, pkgs, ... }:

{
  networking.hostName = "myhost";
  time.timeZone = "Australia/Brisbane";
  system.stateVersion = "24.11";

  # Enable a service
  services.openssh.enable = true;

  # Install system packages
  environment.systemPackages = with pkgs; [
    vim git curl htop
  ];

  # Create a user
  users.users.myuser = {
    isNormalUser = true;
    extraGroups = [ "wheel" "docker" ];
    openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA..." ];
  };
}

Imports

imports = [
  ./hardware-configuration.nix
  ./modules/networking.nix
  ./modules/services.nix
];

Channels and Flakes

Channels

sudo nix-channel --list                       # Show current channels
sudo nix-channel --add https://nixos.org/channels/nixos-24.11 nixos
sudo nix-channel --update                     # Fetch latest channel

Flakes

nix flake update                              # Update all flake inputs
nix flake lock --update-input nixpkgs         # Update a single input
nix flake show                                # Show flake outputs
nix flake metadata                            # Show flake info and inputs

Package Management

nix-env -qaP '.*firefox.*'             # Search packages (channels)
nix search nixpkgs firefox             # Search packages (flakes)
nix-shell -p nodejs python3            # Temporary shell with packages
nix shell nixpkgs#nodejs               # Temporary shell (flakes)
nix run nixpkgs#cowsay -- "hello"      # Run a package without installing
nix-store --gc                         # Garbage collect unused paths
nix-collect-garbage -d                 # Delete old generations + gc
sudo nix-collect-garbage -d            # Same for system profiles
nix path-info -rsSh /run/current-system | sort -k2 -h  # Disk usage by package

Services (systemd)

Nix Configuration

# Enable a built-in service
services.nginx.enable = true;

# Custom systemd service
systemd.services.myapp = {
  description = "My Application";
  after = [ "network.target" ];
  wantedBy = [ "multi-user.target" ];
  serviceConfig = {
    ExecStart = "${pkgs.myapp}/bin/myapp";
    Restart = "on-failure";
    DynamicUser = true;
    StateDirectory = "myapp";
  };
};

Management Commands

systemctl status myapp                 # Service status
systemctl start myapp                  # Start service
systemctl stop myapp                   # Stop service
systemctl restart myapp                # Restart service
journalctl -u myapp -f                 # Follow logs
journalctl -u myapp --since "1 hour ago"
systemctl list-units --type=service    # List all services
systemctl list-units --failed          # Show failed units

Networking

networking = {
  hostName = "myhost";
  domain = "home.arpa";

  # Static IP
  interfaces.eth0.ipv4.addresses = [{
    address = "10.0.0.10";
    prefixLength = 24;
  }];
  defaultGateway = "10.0.0.1";
  nameservers = [ "1.1.1.1" "9.9.9.9" ];

  # Firewall
  firewall = {
    enable = true;
    allowedTCPPorts = [ 22 80 443 ];
    allowedUDPPorts = [ 53 ];
  };

  # VLANs
  vlans.vlan100 = {
    id = 100;
    interface = "eth0";
  };
};

NixOS Containers (declarative)

containers.mycontainer = {
  autoStart = true;
  privateNetwork = true;
  hostBridge = "br0";
  localAddress = "10.0.0.50/24";

  config = { config, pkgs, ... }: {
    services.nginx.enable = true;
    networking.firewall.allowedTCPPorts = [ 80 ];
    system.stateVersion = "24.11";
  };
};

Container Management

sudo nixos-container list                     # List containers
sudo nixos-container status mycontainer       # Container status
sudo nixos-container start mycontainer        # Start
sudo nixos-container stop mycontainer         # Stop
sudo nixos-container root-login mycontainer   # Root shell
sudo nixos-container run mycontainer -- command  # Run a command
sudo machinectl shell mycontainer             # Alternative shell access

Generations and Rollback

sudo nix-env --list-generations -p /nix/var/nix/profiles/system  # List system generations
nixos-rebuild list-generations         # List with details
sudo nixos-rebuild switch --rollback   # Roll back to previous generation
sudo nix-env --delete-generations +5 -p /nix/var/nix/profiles/system  # Keep last 5

From the bootloader: select a previous generation at boot time to recover from a broken config.

Filesystem and Store

nix-store -q --references /run/current-system  # Dependencies of current system
nix-store -q --referrers $(which nginx)        # What depends on this path
nix why-depends /run/current-system $(which openssl)  # Dependency chain
nix-store --verify --check-contents            # Verify store integrity
du -sh /nix/store                              # Total store size

Secrets (sops-nix)

sops.defaultSopsFile = ./secrets/secrets.yaml;
sops.age.keyFile = "/var/lib/sops-nix/key.txt";

sops.secrets."db/password" = {
  owner = "myapp";
  group = "myapp";
};

# Reference in service config
systemd.services.myapp.serviceConfig.EnvironmentFile =
  config.sops.secrets."db/password".path;

Development Shells

shell.nix

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = with pkgs; [
    nodejs
    python3
    terraform
  ];

  shellHook = ''
    echo "Dev shell ready"
  '';
}

direnv Integration

# .envrc
use nix
direnv allow    # Activate the environment

Debugging and Troubleshooting

nixos-rebuild switch 2>&1 | less       # Capture build errors
nix repl '<nixpkgs>'                   # Interactive Nix REPL
nix eval '(import <nixpkgs> {}).nginx.version'  # Evaluate an expression
nixos-option services.nginx.enable     # Query an option's value and definition
man configuration.nix                  # Full NixOS options reference
systemctl --failed                     # Check for failed services after rebuild
journalctl -b -p err                   # Errors since last boot

Common Build Errors

ErrorFix

infinite recursion encountered

Circular reference in config — check imports and let bindings

attribute 'x' missing

Typo in option name or missing module import

collision between packages

Two packages provide the same file — use lib.mkForce or remove one

hash mismatch in fixed-output derivation

Upstream source changed — update the hash with nix-prefetch-url

out of disk space

Run sudo nix-collect-garbage -d to free store space