A customized NixOS image module for Google Compute Engine.
The difference to upstreams module is that we are using systemd-repart to generate disk images, while upstream uses make-disk-image.nix.
By doing so, we loose support for legacy boot, but gain more flexibility with partition layouts and filesystems used as well as performance improvements of the image build. Performance concerns were the primary motivation for this project, as we were seeing excessive memory usage when
building larger (~40GB) images with make-disk-image.nix.
Other then the upstream image, which consists of a single ext4 partition, we pack /nix/store into a read-only erofs partition and mount a writable overlay-store at run-time.
There's an effort to upstream this in NixOS/nixpkgs#463135, but currently waiting for a good way to override
system.build.image. See NixOS/nixpkgs#463249 for discussion.
This work is sponsored by replit
├───nixosConfigurations
│ └───default: NixOS configuration
└───nixosModules
├───nixosModules
│ ├───bloat: NixOS module
│ ├───debug: NixOS module
│ ├───google-compute-repart: NixOS module
│ └───image-script: NixOS module
└───packages
└───x86_64-linux
├───image: package 'google-compute-image-25.11.20251117.89c2b23'
└───imageScript: package 'build-disk-image'
-
packages.x86_64-linux.imageproduces an image ofnixosConfigurations.default, an example configuration of the repositories modules. That image still needs to be renamed todisk.rawand put into a.tar.gzbefore it's ready to be uploaded.imageScriptbelow already includes that step, but we've decided to wait for a solution of NixOS/nixpkgs#463249 before adding it toimage. -
packages.x86_64-linux.imageScriptgenerates a shell script that builds the same image, but without storing the resulting image in/nix/store. The image is written to the current working directory instead. -
nixosModules.google-compute-repartreuses upstreamsgoogle-compute-image.nix, but asserts EFI boot, puts/nix/storeintoerofsand usessystemd-repartto generate the image. -
nixosModules.image-scriptadds thesystem.build.imageScriptattribute to the NixOS closure.nixosModules.debugandnixosModules.bloatare optional modules to aid debugging of early boot and performance testing for larger images. Neither is active by default.
To run the example configuration Google cloud:
# Build the image & note the file name
image=$(nix run .#imageScript)
# Upload it to a bucket
gsutil cp $image "gs://$BUCKET_NAME/"
# Create a VM image from it & mark it UEFI-compatible
gcloud compute images create "$IMAGE_NAME" \
--source-uri="gs://$BUCKET_NAME/$(basename $image)" \
--project="$PROJECT_ID" \
--guest-os-features=UEFI_COMPATIBLE