{"id":14235567,"url":"https://github.com/DeterminateSystems/nix-netboot-serve","last_synced_at":"2025-08-11T00:31:53.616Z","repository":{"id":38360899,"uuid":"402140692","full_name":"DeterminateSystems/nix-netboot-serve","owner":"DeterminateSystems","description":"Make any NixOS system netbootable with 10s cycle times.","archived":false,"fork":false,"pushed_at":"2024-07-24T14:19:31.000Z","size":189,"stargazers_count":196,"open_issues_count":5,"forks_count":11,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-08-21T21:27:11.510Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DeterminateSystems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-01T17:05:39.000Z","updated_at":"2024-08-08T06:30:06.000Z","dependencies_parsed_at":"2024-04-19T14:07:06.015Z","dependency_job_id":null,"html_url":"https://github.com/DeterminateSystems/nix-netboot-serve","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeterminateSystems%2Fnix-netboot-serve","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeterminateSystems%2Fnix-netboot-serve/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeterminateSystems%2Fnix-netboot-serve/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeterminateSystems%2Fnix-netboot-serve/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DeterminateSystems","download_url":"https://codeload.github.com/DeterminateSystems/nix-netboot-serve/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229478677,"owners_count":18079372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-20T21:02:06.343Z","updated_at":"2024-12-13T01:30:24.353Z","avatar_url":"https://github.com/DeterminateSystems.png","language":"Rust","funding_links":[],"categories":["Rust","Installation Media"],"sub_categories":[],"readme":"# nix-netboot-serve\n\nDynamically generate netboot images for arbitrary NixOS system closures,\nprofiles, or configurations with 10s iteration times.\n\n## Usage\n\nCreate working directories for it:\n\n```\nmkdir ./gc-roots ./profiles ./configurations ./cpio-cache\n```\n\nThen start up the server:\n\n```\nRUST_LOG=info cargo run -- --gc-root-dir ./gc-roots --config-dir ./configurations --profile-dir ./profiles/ --cpio-cache-dir ./cpio-cache/ --listen 127.0.0.1:3030\n```\n\nSee `./boot.sh` for an example of booting with QEMU.\n\n## Booting an absolute closure\n\n### How To\n\nTo boot from a specific closure like\n`/nix/store/0m60ngchp6ki34jpwmpbdx3fby6ya0sf-nixos-system-nginx-21.11pre307912.fe01052444c`,\nuse `/boot/0m60ngchp6ki34jpwmpbdx3fby6ya0sf-nixos-system-nginx-21.11pre307912.fe01052444c/netboot.ipxe`\nas your chain url.\n\n## Behavior\n\nAs long as that closure exists on the host, that closure will always\nbe booted, unchanged.\n\n## Booting a profile\n\n### How To\n\nIn the `profiles` directory, create symlinks to top level system paths.\nFor example:\n\n```console\n$ ls -la profiles/\nexample-host -\u003e /nix/store/4y829p7lljdvwnmsk6pnig3mlh6ygklj-nixos-system-example-host-21.11pre130979.gfedcba\n```\n\nthen use `/dispatch/profile/example-host` to boot it.\n\n### Behavior\n\nThe symlink will be resolved every time a machine boots.\n\n## Booting a configuration\n\n### How To\nIn the `configurations` directory, create a directory for each system,\nand create a `default.nix` inside. For example:\n\n```console\n$ tree configurations/\nconfigurations/\n└── m1.small\n    └── default.nix\n```\n\nIn the `default.nix`, create an expression with your NixOS configuration\nready to be built:\n\n```nix\n(import \u003cnixpkgs/nixos\u003e {\n    configuration = { pkgs, ... }: {\n        networking.hostName = \"m1small\";\n        environment.systemPackages = [ pkgs.hello ];\n        fileSystems.\"/\" = {\n            device = \"/dev/bogus\";\n            fsType = \"ext4\";\n        };\n        boot.loader.grub.devices = [ \"/dev/bogus\" ];\n        boot.postBootCommands = ''\n            PATH=${pkgs.nix}/bin /nix/.nix-netboot-serve-db/register\n        '';\n    };\n}).system\n```\n\nThen use `/dispatch/configuration/m1.small` to boot it.\n\n## Booting from Hydra\n\n### How To\n\nCreate a Hydra project and jobset which contains a job which produces a\nbootable system configuration.\n\nThen use the URL `/dispatch/hydra/HOSTNAME/PROJECT/JOBSET/JOB`, substituting\nthose URL sections with names from your system to boot it.\n\nNote that nix-netboot-serve will query the provided Hydra for the store path\nto boot and will then try to substitute the closure. Nix must already be\nconfigured with the requested hydra's cache for this to work.\n\n### Behavior\n\nThe configuration will be `nix-build` once per boot, and create a symlink\nin the `--gc-root-dir` directory with the same name as the configuration.\n\nIf the build fails, the ipxe client will be told to retry in 5s.\n\nNote: there is currently a buggy race condition. In the following circumstance:\n\n1. machine A turns on\n1. machine B turns on\n1. machine A hits the build URL and a long build starts\n1. you change the configuration to have a very short build\n1. machine B hits the build URL and the short build starts\n1. machine B's configuration finishes building\n1. machine B boots the short build configuration\n1. machine A's configuration finishes building\n1. machine A boots the **short configuration** instead of the long configuration\n\n## Theory of Operation\n\nLinux's boot process starts with two things:\n\n1. the kernel\n1. an initrd, or an initial ram disk\n\nThe ramdisk has all the files needed to mount any disks and start any\nsoftware needed for the machine. Typically the ramdisk is constructed\nof a [CPIO](https://en.wikipedia.org/wiki/Cpio), a very simple file\narchive.\n\nLinux supports a special case of its initrd being comprised of\n_multiple_ CPIOs. By simply concatenating two CPIOs together,\nLinux's boot process will see the merged contents of both CPIOs.\n\nFurthermore, individual CPIOs can be compressed independently,\nmerged together with concatenation, and Linux will decompress\nand read each CPIO independently.\n\nA NixOS system is comprised of hundreds of independent, immutable\n`/nix/store` paths.\n\nMerging these together, we can dynamically create a single, compressed\nCPIO per Nix store path and cache it for later.\n\nWhen a new boot request comes in, the software fetches the list of\nNix store paths for the requested NixOS system. Then, every path\nhas a CPIO built for it. Once each store path has a CPIO, the results\nare streamed back to the iPXE client. By caching the resulting CPIO,\niterative development on a system configuration can result in just\n3-5 new CPIOs per change.\n\n## Improvements over NixOS's NetBoot Support\n\nNixOS's NetBoot image creation support works well, however iterating\non a single closure involves recreating the CPIO and recompressing for\nevery store path every time. This can add several minutes to cycle\ntime.\n\n## Other API Information\n\n* Get the size of the initrd: `HEAD /boot/PATH/initrd`\n* Pass additional kernel commandline arguments: `/dispatch/...?cmdline_prefix_args=...\u0026cmdline_suffix_args=...`\n\n## Caveats\n\n### Loading the Nix Database\n\nBefore using Nix inside the booted machine, make sure to **load the Nix\ndatabase**. To do that, add this to your NixOS configuration:\n\n```\n{ pkgs, ... }: {\n    boot.postBootCommands = ''\n        PATH=${pkgs.nix}/bin /nix/.nix-netboot-serve-db/register\n    '';\n}\n```\n\nThis is not necessary if the system will not execute Nix commands.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeterminateSystems%2Fnix-netboot-serve","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDeterminateSystems%2Fnix-netboot-serve","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeterminateSystems%2Fnix-netboot-serve/lists"}