Atomic, image-based systems with A/B updates - provisioned using Nix.
pattern is not a distro, but provides a base module for building your own systems! See Explanation for more information.
- Base image generated using
systemd-repart - Verity on erofs root Nix Store using
systemd-veritysetup - Inflatable TPMv2 LUKS-encrypted persistent partition using
systemd-repart - Signed A/B store updates using
systemd-sysupdate - Optional unprivileged user setup on first boot using
systemd-homed - Optional distrobox, bubblewrap and xdg-dbus-proxy to install and sandbox apps
- Optional Minimal GNOME desktop
pattern provides a base module which can be used to implement concepts from Fitting Everything Together using Nix!
pattern is primarily developed for my own personal use. Its design and priorities are driven by my requirements. The documentation is written to help me create new systems.
pattern primarily ships the nixosModules.pattern which you can import in your
NixOS configuration to combine with usual options from the NixOS modules system
to build your own base images. See Usage for more information.
pattern also provides some of its own options to configure aspects of the
nixosModules.pattern. See Options for all included options.
This section covers using pattern to build your own base images.
-
Add pattern to your flake inputs:
inputs.pattern.url = "github:sotormd/pattern";
-
Create a NixOS configuration output and add
inputs.pattern.nixosModules.pattern. Example:outputs = { self, ... }@inputs: { nixosConfigurations.mySystem = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ inputs.pattern.nixosModules.pattern # add this ./configuration.nix # rest of your configuration ]; }; };
-
Configure your system by making changes like you would to any other NixOS configuration. Make sure to add modules that your hardware may require. You may also want to set an initial root password.
-
Set the options required by pattern. See Options for more information. Some of the options are compulsory.
-
You probably want to generate GPG signing keys so that
systemd-sysupdatecan verify against them. You can use your own keys or use the included script to generate new ones:nix run github:sotormd/pattern#gen-keyring -- mySystem
This will create
mySystem-gpg/andmySystem-pubring.pgp.Remember to pass
mySystem-pubring.pgptopattern.image.updates.pubringvia Options to embed it in the base image.mySystem-gpg/contains the private key and should be kept secret. -
Once you are done, you can build your base image:
nix build .#nixosConfigurations.mySystem.config.pattern.release
-
To create the final signed release artifact:
nix run github:sotormd/pattern#sign-release -- ./result ./mySystem-gpg
This creates the final release in
./pattern-release -
The
./pattern-releasedirectory will include a full base image + individual partitions. The individual partitions are for updating the system. To install your base system, we will use the full image. This full raw image can be written to a disk usingddand booted from. -
While serving updates, just upload the contents of
./pattern-releaseto your update server.
This section documents the options provided by nixosModules.pattern.
All options are available under the pattern namespace.
Options related to image identity and updates.
- Type:
string - Required: yes
A unique identifier for the image.
This is used to distinguish different systems when performing updates. It should remain consistent across releases of the same system.
- Type:
string - Required: yes
The version of the image.
Used by the update system to determine whether a newer version is available and to label boot entries.
- Type:
string - Required: yes
The base URL used by systemd-sysupdate to fetch updates.
pattern does not impose any restrictions on how updates are delivered. Any
transport may be used as long as updates are compatible with
systemd-sysupdate.
- Type:
path - Required: yes
The path to the public GPG key used by systemd-sysupdate to verify updates.
Options related to partition layout and persistence.
- Type:
string - Required: yes
The target disk device used when generating the image (e.g. /dev/sda).
This is used by systemd-repart when creating the partition layout.
Defines the sizes of partitions created in the base image.
All values are strings and should follow systemd-repart size syntax (e.g.
512M, 1G).
- Type:
string - Required: yes
Size of the EFI System Partition (ESP).
- Type:
string - Required: yes
Size of the verity hash partition used for root filesystem integrity.
- Type:
string - Required: yes
Size of the root (/usr) filesystem image.
Controls which directories are persisted across reboots.
By default, the root filesystem is ephemeral. Enabling persistence for a directory ensures it is stored on a separate writable partition.
All options are booleans and false by default.
Persist /etc.
Persist /home.
Persist /srv.
Persist /var.
- Type:
boolean - Default:
true
Enables root autologin for debugging purposes.
This should be disabled for production systems.
Optional userspace features provided by pattern.
These are disabled by default. Users are free to implement their own userspace environment.
- Type:
boolean - Default:
false
Enable systemd-homed for user management. Also allows setting up a main
unprivileged user on first boot.
- Type:
boolean - Default:
false
Enable a minimal desktop environment.
- Type:
boolean - Default:
false
Enable distrobox for managing application containers.
- Type:
boolean - Default:
false
Enable additional sandboxing tools such as bubblewrap and xdg-dbus-proxy.
- pattern provides a base system only. Many aspects (such as update transport and application model) are intentionally left to the user.