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```