OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 070

Building a bootable NixOS ISO

Customize software, graphical desktops, and bootable images through installation-media modules.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSNixOS virtualization and deployment ↗
About 2 min readStart reading

Version scope: the examples below retain the tutorial's NixOS 24.05 context; that release is no longer maintained. For a real project, choose a supported release, pin the nixpkgs revision, and check the corresponding options. system.stateVersion defines a compatibility baseline and should not be changed mechanically on every upgrade. The commands in this article are teaching examples and have not been run or verified on the target system.

Overview#

NixOS can build custom bootable ISO images for:

  • Creating custom installation media
  • Making system maintenance media
  • Deploying preconfigured systems

Basic configuration#

Create an iso.nix file:

{ pkgs, modulesPath, ... }:

{
  imports = [
    (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")
  ];

  # ISO 标识
  isoImage.makeEfiBootable = true;
  isoImage.makeUsbBootable = true;
  
  # 主机名
  networking.hostName = "nixos-custom";
  
  # 预装软件
  environment.systemPackages = with pkgs; [
    vim
    git
    htop
    parted
    gparted
  ];
  
  # 系统版本
  system.stateVersion = "24.05";
}

Building the ISO#

# 构建 ISO
nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage \
  -I nixos-config=./iso.nix \
  -I nixpkgs=channel:nixos-24.05

The generated ISO is in ./result/iso/. Its filename depends on the build configuration; confirm it with ls ./result/iso/ rather than assuming a fixed name.

A graphical ISO#

An ISO with the GNOME desktop environment:

{ pkgs, modulesPath, ... }:

{
  imports = [
    (modulesPath + "/installer/cd-dvd/installation-cd-graphical-gnome.nix")
  ];

  # 添加额外的软件
  environment.systemPackages = with pkgs; [
    firefox
    libreoffice
  ];
}

Building with Flakes#

# flake.nix
{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
  
  outputs = { self, nixpkgs }: {
    nixosConfigurations.iso = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        (nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
        ({ pkgs, ... }: {
          isoImage.makeEfiBootable = true;
          networking.hostName = "nixos-live";
          environment.systemPackages = [ pkgs.vim ];
        })
      ];
    };
  };
}

Build:

nix build .#nixosConfigurations.iso.config.system.build.isoImage

Writing the ISO to a USB drive#

Writing the image overwrites the entire target drive. Back up the target USB drive first, confirm its model, capacity, and device path, and unmount its mounted partitions. The target must be the whole drive, not an individual partition. Replace the placeholder below; do not run the command as written.

# 查看设备身份与挂载状态
lsblk -o NAME,SIZE,MODEL,TYPE,MOUNTPOINTS
ls ./result/iso/

# 确认目标后,逐个卸载其已挂载的分区
sudo umount /dev/<USB_PARTITION>

# 写入已经核对过的 ISO 和整盘设备
sudo dd if=./result/iso/<BUILT_IMAGE>.iso of=/dev/<USB_DISK> bs=4M status=progress conv=fsync
sync

A successful ISO build does not guarantee a successful boot on physical hardware. You can first test the boot menu and required software in QEMU, then check UEFI/BIOS support, drivers, and networking on the target hardware.

References & further reading

  1. nix.dev ISO tutorial ↗
  2. NixOS installation manual ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

NixOS virtualization and deployment

  1. 01Validating NixOS configuration with QEMU
  2. 02Building a bootable NixOS ISO
  3. 03Building and running container images with dockerTools
  4. 04Deploying NixOS over SSH
  5. 05Dividing deployment responsibilities between Terraform and NixOS
  6. 06Designing layered desktop and development environments
CONTINUE READING / NEXT ARTICLEBuilding and running container images with dockerTools

Manage application derivations, runtime closures, and container data state separately.