1# Building Images via `systemd-repart` {#sec-image-repart} 2 3You can build disk images in NixOS with the `image.repart` option provided by 4the module [image/repart.nix][]. This module uses `systemd-repart` to build the 5images and exposes it's entire interface via the `repartConfig` option. 6 7[image/repart.nix]: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/image/repart.nix 8 9An example of how to build an image: 10 11```nix 12{ config, modulesPath, ... }: 13{ 14 15 imports = [ "${modulesPath}/image/repart.nix" ]; 16 17 image.repart = { 18 name = "image"; 19 partitions = { 20 "esp" = { 21 contents = { 22 # ... 23 }; 24 repartConfig = { 25 Type = "esp"; 26 # ... 27 }; 28 }; 29 "root" = { 30 storePaths = [ config.system.build.toplevel ]; 31 repartConfig = { 32 Type = "root"; 33 Label = "nixos"; 34 # ... 35 }; 36 }; 37 }; 38 }; 39 40} 41``` 42 43## Nix Store Paths {#sec-image-repart-store-paths} 44 45If you want to rewrite Nix store paths, e.g., to remove the `/nix/store` prefix 46or to nest it below a parent path, you can do that through the 47`nixStorePrefix` option. 48 49### Nix Store Partition {#sec-image-repart-store-partition} 50 51You can define a partition that only contains the Nix store and then mount it 52under `/nix/store`. Because the `/nix/store` part of the paths is already 53determined by the mount point, you have to set `nixStorePrefix = "/"` so 54that `/nix/store` is stripped from the paths before copying them into the image. 55 56```nix 57{ 58 fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store"; 59 60 image.repart.partitions = { 61 "store" = { 62 storePaths = [ config.system.build.toplevel ]; 63 nixStorePrefix = "/"; 64 repartConfig = { 65 Type = "linux-generic"; 66 Label = "nix-store"; 67 # ... 68 }; 69 }; 70 }; 71} 72``` 73 74### Nix Store Subvolume {#sec-image-repart-store-subvolume} 75 76Alternatively, you can create a Btrfs subvolume `/@nix-store` containing the 77Nix store and mount it on `/nix/store`: 78 79```nix 80{ 81 fileSystems."/" = { 82 device = "/dev/disk/by-partlabel/root"; 83 fsType = "btrfs"; 84 options = [ "subvol=/@" ]; 85 }; 86 87 fileSystems."/nix/store" = { 88 device = "/dev/disk/by-partlabel/root"; 89 fsType = "btrfs"; 90 options = [ "subvol=/@nix-store" ]; 91 }; 92 93 image.repart.partitions = { 94 "root" = { 95 storePaths = [ config.system.build.toplevel ]; 96 nixStorePrefix = "/@nix-store"; 97 repartConfig = { 98 Type = "root"; 99 Label = "root"; 100 Format = "btrfs"; 101 Subvolumes = "/@ /@nix-store"; 102 MakeDirectories = "/@ /@nix-store"; 103 # ... 104 }; 105 }; 106 }; 107} 108``` 109 110## Appliance Image {#sec-image-repart-appliance} 111 112The `image/repart.nix` module can also be used to build self-contained [software 113appliances][]. 114 115[software appliances]: https://en.wikipedia.org/wiki/Software_appliance 116 117The generation based update mechanism of NixOS is not suited for appliances. 118Updates of appliances are usually either performed by replacing the entire 119image with a new one or by updating partitions via an A/B scheme. See the 120[Chrome OS update process][chrome-os-update] for an example of how to achieve 121this. The appliance image built in the following example does not contain a 122`configuration.nix` and thus you will not be able to call `nixos-rebuild` from 123this system. Furthermore, it uses a [Unified Kernel Image][unified-kernel-image]. 124 125[chrome-os-update]: https://chromium.googlesource.com/aosp/platform/system/update_engine/+/HEAD/README.md 126[unified-kernel-image]: https://uapi-group.org/specifications/specs/unified_kernel_image/ 127 128```nix 129let 130 pkgs = import <nixpkgs> { }; 131 efiArch = pkgs.stdenv.hostPlatform.efiArch; 132in 133(pkgs.nixos [ 134 ( 135 { 136 config, 137 lib, 138 pkgs, 139 modulesPath, 140 ... 141 }: 142 { 143 144 imports = [ "${modulesPath}/image/repart.nix" ]; 145 146 boot.loader.grub.enable = false; 147 148 fileSystems."/".device = "/dev/disk/by-label/nixos"; 149 150 image.repart = { 151 name = "image"; 152 partitions = { 153 "esp" = { 154 contents = { 155 "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = 156 "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi"; 157 158 "/EFI/Linux/${config.system.boot.loader.ukiFile}".source = 159 "${config.system.build.uki}/${config.system.boot.loader.ukiFile}"; 160 }; 161 repartConfig = { 162 Type = "esp"; 163 Format = "vfat"; 164 SizeMinBytes = "96M"; 165 }; 166 }; 167 "root" = { 168 storePaths = [ config.system.build.toplevel ]; 169 repartConfig = { 170 Type = "root"; 171 Format = "ext4"; 172 Label = "nixos"; 173 Minimize = "guess"; 174 }; 175 }; 176 }; 177 }; 178 179 } 180 ) 181]).image 182```