Skip to content

3.Getting Started With Nucleus

Muhammad Talha edited this page Sep 21, 2026 · 4 revisions

Getting Started With Nucleus

Getting started with nucleus is not backward compatible with your existing NixOS instance. Nucleus is designed for NixOS users that are overwhelmed by tons of different approaches for configuring your NixOS systems.

Important

  1. Only UEFI systems are supported.
  2. Fresh Installation is the only way for getting started.

The Mental Model for Flakes in Nucleus

In Nucleus, flakes are simply considered as piecewise functions that takes set of some flakes as input and give some outputs when a specific condition is triggered (in the case of nucleus, the output is a host instance and the condition is succeeding of build). In continuation to the above statement, consider the schematic diagrams from Working Model, flake is visualized as a piecewise function f in the given figure.

pasted-code

Just like the piecewise function in math, a flake in the context of Nucleus can give only one output per host.

Installing NixOS via Nucleus

Note

For installing NixOS via Nucleus, it is recommended to use minimal ISO. The demonstrated method is same for any starter. For the sake of simplicity, I am continuing the tutorial with minimal starter.

In contrast to regular minimal installation, nucleus will feel a lot more easier yet also much more different.

Once in a live a ISO session, the first and foremost step is to enter the root account with sudo -i. After that, execute the following commands one by one.

Prepare The Environment

Since flakes and commands like nix flake|run|... are still experimental in NixOS, we have to enable those features for our installation session by exporting custom environment variable.

export NIX_CONFIG="experimental-features = flakes nix-command"

Initializing The Starter

Nucleus provides following three starting points by default as of 2026-09-18.

  1. Minimal — No Desktop Session, Only Core Operating System Essentials.
  2. KDE — Core Operating System Essentials plus K Desktop Environment.
  3. GNOME — Core Operating System Essentials plus GNOME Desktop Environment.

Once you have activated the root account, run the following command to initialize the starter.

Note

Replace minimal with gnome or kde as per your choice.

nix flake init -t github:muhammadtalha-quant/nucleus/latest#minimal

Preparing The Starter

Once the starter is initialized, we will edit the flake.nix to prepare for building/installing the first host instance.

vim flake.nix

At first glance, flake.nix will look like this.

Click to expand/collapse
{
  description = "A minimal starter for NixOS based on Nucleus Architecture.";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    import-tree.url = "github:denful/import-tree";
    disko = {
      url = "github:nix-community/disko/latest";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs =
    {
      self,
      nixpkgs,
      home-manager,
      disko,
      ...
    }@inputs:
    let
      hashedRootPassword = "STDOUT OF 'mkpasswd -m yescrypt YOUR_DESIRED_ROOT_PASSWORD'";

      # !=== HOSTS DEFINITION ===!
      hosts = {
        laptop = {
          hostName = "DESIRED_HOSTNAME";
          stateVersion = "YEAR.RELEASE OF THE ISO YOU ARE INSTALLING FROM";
          timeZone = "REGION/CITY";
          disko = {
            storageDevice = "/dev/DEVICE";
            swapSize = "8G";
          };
        };
      };

      # !=== USERS DEFINITION ===!
      users = {
        primary = {
          userName = "DESIRED_USERNAME";
          realName = "YOUR REAL NAME";
          hashedPassword = "STDOUT OF 'mkpasswd -m yescrypt YOUR_DESIRED_USER_PASSWORD'";
          emailAddress = "you@mailbox.com";
          gpgKey = "XXXXXXXXXXXXXXXX";
        };
      };

      # !=== ENVIRONMENT CONFIG ===!
      configDirectory = "/etc/nixos/";

      # !=== HOME MANAGER ===!
      hmArgs = {
        inherit (users.primary) emailAddress;
        inherit (users.primary) userName;
        inherit (users.primary) realName;
        inherit (users.primary) gpgKey;
      };
    in
    {
      diskoConfigurations.${hosts.laptop.hostName} =
        import ./modules/common/disko/bare-ext4.nix hosts.laptop.disko;
      nixosConfigurations.${hosts.laptop.hostName} = nixpkgs.lib.nixosSystem {
        inherit
          (
            (builtins.fromJSON (
              builtins.readFile ./modules/hosts/${hosts.laptop.hostName}/hardware_report.json
            ))
          )
          system
          ;
        specialArgs = {
          inherit hashedRootPassword;
          inherit hmArgs;
          inherit inputs;
          inherit configDirectory;
          inherit users;
          inherit (hosts.laptop.disko) swapSize;
          inherit (hosts.laptop.disko) storageDevice;
          inherit (hosts.laptop) hostName;
          inherit (hosts.laptop) timeZone;
          inherit (hosts.laptop) stateVersion;
        };
        modules = [
          ./modules/common/nixos-core/core.nix
          ./modules/features/workstation/workstation.nix
          ./modules/hosts/${hosts.laptop.hostName}/default.nix
          home-manager.nixosModules.home-manager
          ./modules/features/home-manager/decl.nix
          disko.nixosModules.disko
          ./modules/common/disko/bare-ext4.nix
        ];
      };
    };
}

Tip

  • inherit X; means that some internal features or common module expects some field whose name is X. If X is not defined in current scope, then you can pass it as X = SOME_VALUE.
  • inherit (set) X; have the same meaning as standard inherit but the only difference is that X is extracted/chosen from attribute set named set.
  • let ... in means that ... are exported to the next scope. ... means variables in general.
  • builtins.fromJSON converts standard JSON into an attribute set.
  • builtins.readFile reads the file located at the given directory.
  • nixosConfigurations.${...} is responsible for building the host instance with the hostname ....
  • diskoConfigurations.${...} is responsible for automating the process of partitioning for the hostname ....

Setting Root and User Passwords

For Root Password:

  1. Inside vim, scroll down and locate the hashedRootPassword variable.
  2. Position your cursor on the opening quotation mark of the value.
  3. Press Escape to enter command mode.
  4. Type di" to delete everything inside the quotation marks.
  5. Type :terminal mkpasswd -m yescrypt YOUR_DESIRED_ROOT_PASSWORD and press Enter.
  6. This opens a focused split terminal showing the hashed password.
  7. Copy the hash using yy (copy line) or y$ (copy to end of line).
  8. Close the terminal split by typing :close.
  9. Paste the copied hash between the quotation marks.

For User Password:

  1. Locate the hashedPassword field under users.primary.
  2. Repeat the same procedure as above using your desired user password in step 5.
  3. Replace the placeholder hash with your copied user password hash.

Configuring Disko

Disko is configured per host inside the host definition (for example hosts.laptop).

Steps:

  1. In flake.nix, find the host entry you intend to install. The host name must not contain hyphens.
  2. Locate the disko = { ... } block inside that host.
  3. From within vim, open a terminal split to list disks: :terminal lsblk.
  4. Identify the target device (for example /dev/sda) and replace /dev/DEVICE with that device path.
  5. Close the terminal split by typing :close.
  6. Adjust the swapSize field, which controls the swap or zram partition size.

Keep changes minimal and verify device names carefully to avoid data loss.


Setting miscellaneous data

Fill these host fields before proceeding:

  • Time zone: set timeZone to your region (for example Europe/London).
  • State version: set stateVersion to match the ISO release version of the installer image.
  • Email address: set the email used by git and GitHub.
  • Real name: set the name used in git commits.
  • GPG key ID: (optional) public key ID for signing commits and tags. Leave empty if you don't have one.
  • Hostname: set hostName to register your host blueprint.

To import an existing GPG key pair after installation, run gpg --import private.asc and gpg --import public.asc. If you have no key, generate one after first boot with gpg --full-generate-key.


Formatting, partitioning and mounting the target disk

  1. Save and exit vim: :wqa.
  2. Run the disko command (replace DESIRED_HOSTNAME with your host name):
nix run github:nix-community/disko/latest -- --mode destroy,format,mount -f .#DESIRED_HOSTNAME

Note

  • The default bare-ext4.nix creates an unencrypted ext4 layout with a 1GB boot partition, a swap partition of the size you specified in swapSize, and a root partition using the remaining space.
  • To use a different layout, adapt an example from the disko examples and make it compatible with Nucleus.
  • For detailed disko configuration information, see the disko repository. Disko specifics are beyond the scope of this guide.
  1. Persist the generated configuration to the target system:
mkdir -p /mnt/etc/nixos
mv * /mnt/etc/nixos
cd /mnt/etc/nixos

Generating Hardware Report

We will use nixos-facter, a very handy tool to generate exact and accurate hardware report for the current host.

Replace DESIRED_HOSTNAME with the host name you declared in steps above above.

cd modules/hosts/DESIRED_HOSTNAME
nix run nixpkgs#nixos-facter -- -o hardware_report.json

Installing from Nucleus

Run the installer from the live session (replace DESIRED_HOSTNAME):

cd /mnt/etc/nixos
nixos-install --flake .#DESIRED_HOSTNAME --no-root-passwd

What this does:

  • Builds and installs the NixOS configuration declared for the chosen host.
  • --no-root-passwd is safe because the root password is already defined in flake.nix.

Post-install checklist

After installation completes:

  1. Reboot the machine and remove the installation media.
  2. Verify the system boots and the hostname matches the one in flake.nix.
  3. Log in and confirm user accounts and SSH keys work as expected.
  4. If you plan to use GPG signing, generate or import keys now and configure git accordingly.
  5. Consult these webpages for the ultimate option and package lookup.
  6. Start version controlling your NixOS configuration from day one.
  7. Take your time and read through your configuration and build your understanding of nucleus.
  8. If you want to learn from a more robust configuration built on top of nucleus, take a look at my personal dotfiles

Tip

Nucleus bundles nh (nix-helper) by default — a tool that simplifies system management. Familiarize yourself with these commands:

  • nh os switch — Build, activate, and add the new generation to the bootloader menu.
  • nh os boot — Build and add the generation to the bootloader without activating it.
  • nh os test — Test a generation temporarily without adding it to the bootloader. Disables rollback until reboot.
  • nh os info — Display a quick overview of all system generations.
  • nh os rollback --to <generation_number> — Switch to a previous or newer generation without rebooting.