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 imports = [ "${modulesPath}/image/repart.nix" ]; 15 16 image.repart = { 17 name = "image"; 18 partitions = { 19 "esp" = { 20 contents = { 21 ... 22 }; 23 repartConfig = { 24 Type = "esp"; 25 ... 26 }; 27 }; 28 "root" = { 29 storePaths = [ config.system.build.toplevel ]; 30 repartConfig = { 31 Type = "root"; 32 Label = "nixos"; 33 ... 34 }; 35 }; 36 }; 37 }; 38 39} 40``` 41 42## Nix Store Partition {#sec-image-repart-store-partition} 43 44You can define a partition that only contains the Nix store and then mount it 45under `/nix/store`. Because the `/nix/store` part of the paths is already 46determined by the mount point, you have to set `stripNixStorePrefix = true;` so 47that the prefix is stripped from the paths before copying them into the image. 48 49```nix 50fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store" 51 52image.repart.partitions = { 53 "store" = { 54 storePaths = [ config.system.build.toplevel ]; 55 stripNixStorePrefix = true; 56 repartConfig = { 57 Type = "linux-generic"; 58 Label = "nix-store"; 59 ... 60 }; 61 }; 62}; 63``` 64 65## Appliance Image {#sec-image-repart-appliance} 66 67The `image/repart.nix` module can also be used to build self-contained [software 68appliances][]. 69 70[software appliances]: https://en.wikipedia.org/wiki/Software_appliance 71 72The generation based update mechanism of NixOS is not suited for appliances. 73Updates of appliances are usually either performed by replacing the entire 74image with a new one or by updating partitions via an A/B scheme. See the 75[Chrome OS update process][chrome-os-update] for an example of how to achieve 76this. The appliance image built in the following example does not contain a 77`configuration.nix` and thus you will not be able to call `nixos-rebuild` from 78this system. 79 80[chrome-os-update]: https://chromium.googlesource.com/aosp/platform/system/update_engine/+/HEAD/README.md 81 82```nix 83let 84 pkgs = import <nixpkgs> { }; 85 efiArch = pkgs.stdenv.hostPlatform.efiArch; 86in 87(pkgs.nixos [ 88 ({ config, lib, pkgs, modulesPath, ... }: { 89 90 imports = [ "${modulesPath}/image/repart.nix" ]; 91 92 boot.loader.grub.enable = false; 93 94 fileSystems."/".device = "/dev/disk/by-label/nixos"; 95 96 image.repart = { 97 name = "image"; 98 partitions = { 99 "esp" = { 100 contents = { 101 "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = 102 "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi"; 103 104 "/loader/entries/nixos.conf".source = pkgs.writeText "nixos.conf" '' 105 title NixOS 106 linux /EFI/nixos/kernel.efi 107 initrd /EFI/nixos/initrd.efi 108 options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} 109 ''; 110 111 "/EFI/nixos/kernel.efi".source = 112 "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}"; 113 114 "/EFI/nixos/initrd.efi".source = 115 "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; 116 }; 117 repartConfig = { 118 Type = "esp"; 119 Format = "vfat"; 120 SizeMinBytes = "96M"; 121 }; 122 }; 123 "root" = { 124 storePaths = [ config.system.build.toplevel ]; 125 repartConfig = { 126 Type = "root"; 127 Format = "ext4"; 128 Label = "nixos"; 129 Minimize = "guess"; 130 }; 131 }; 132 }; 133 }; 134 135 }) 136]).image 137```