{
  "manifest_version": "1",
  "slug": "nix-builder",
  "title": "Nix remote builder",
  "headline": "Run a Nix remote builder and binary cache on exe.dev",
  "description": "Send Nix builds from your Mac, Linux machines, and CI to a big exe.dev VM over SSH, and serve its store as a signed, private binary cache.",
  "category": "dev-tools",
  "tags": [
    "nix remote builder",
    "nix distributed builds",
    "nix binary cache",
    "harmonia",
    "nix-serve",
    "attic",
    "cachix alternative",
    "nix ci",
    "nix-darwin linux builder"
  ],
  "url": "https://exe.dev/deploy/nix-builder",
  "markdown_url": "https://exe-staging.dev/deploy/nix-builder.md",
  "upstream": {
    "website": "https://nix.dev/manual/nix/latest/advanced-topics/distributed-builds",
    "source": "https://github.com/nix-community/harmonia",
    "docs": "https://nix.dev/manual/nix/latest/command-ref/conf-file",
    "license": "LGPL-2.1 (Nix), MIT (Harmonia)"
  },
  "example_vm_name": "my-nix-builder",
  "time": "15 minutes",
  "stack": [
    {
      "name": "Nix 2.35",
      "detail": "the official multi-user install; nix-daemon builds as exedev's trusted proxy, on every core",
      "data": "/nix/store, /nix/var/nix/db"
    },
    {
      "name": "Harmonia 3.3",
      "detail": "serves /nix/store as a binary cache, signing every path; the harmonia systemd service",
      "port": 8000,
      "data": "/etc/harmonia/harmonia.toml"
    },
    {
      "name": "Signing key",
      "detail": "my-nix-builder-1, made on the VM; clients trust its public half",
      "data": "/etc/nix/cache-key.sec, /etc/nix/cache-key.pub"
    },
    {
      "name": "Garbage collection",
      "detail": "harmonia-gc nightly, plus Nix's own min-free during builds"
    }
  ],
  "access": [
    {
      "url": "ssh-ng://my-nix-builder.exe.xyz",
      "who": "private",
      "what": "remote builds, for SSH keys you add with ssh-key add --vm"
    },
    {
      "url": "https://my-nix-builder.exe.xyz/",
      "who": "private",
      "what": "the binary cache, for your exe.dev login or a VM token"
    }
  ],
  "delivers": [
    "Nix with nix-daemon, `exedev` as a trusted user, building on every core, reachable over `ssh-ng://` through exe.dev's SSH",
    "A signing key made on the VM, its public key printed for clients",
    "Harmonia serving the store as a signed binary cache on port 8000, private behind the HTTPS proxy",
    "A nightly harmonia-gc that keeps 25% of the disk free and everything from the last 14 days, and Nix's own collection when a build runs low",
    "A test build on the VM whose output the cache serves with the VM's signature"
  ],
  "deployable": true,
  "deploy": {
    "new_vm_url": "https://exe-staging.dev/new?prompt=Set%20up%20Nix%20remote%20builder%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fnix-builder.md%20from%20top%20to%20bottom.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-nix-builder.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-nix-builder.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AThis%20recipe%20needs%20a%20200GB%20disk%2C%20and%20a%20new%20VM%27s%20may%20be%20smaller.%20Before%20you%20install%20anything%2C%20run%20%60df%20-h%20%2F%60.%20If%20its%20size%20is%20under%20180G%2C%20stop%20and%20ask%20me%20to%20grow%20the%20disk%2C%20either%20with%20this%20link%3A%20https%3A%2F%2Fexe.dev%2Fsuggest%3Fcommand%3Dresize%2520my-nix-builder%2520--disk%253D200GB%20or%2C%20on%20my%20computer%2C%20with%20%60ssh%20exe.dev%20resize%20my-nix-builder%20--disk%3D200GB%60.%20When%20I%20say%20it%27s%20done%2C%20run%20%60sudo%20resize2fs%20%22%24%28findmnt%20-no%20SOURCE%20%2F%29%22%60%2C%20check%20%60df%20-h%20%2F%60%20again%2C%20and%20carry%20on.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20Nix%20with%20nix-daemon%2C%20%60exedev%60%20as%20a%20trusted%20user%2C%20building%20on%20every%20core%2C%20reachable%20over%20%60ssh-ng%3A%2F%2F%60%20through%20exe.dev%27s%20SSH%0A-%20A%20signing%20key%20made%20on%20the%20VM%2C%20its%20public%20key%20printed%20for%20clients%0A-%20Harmonia%20serving%20the%20store%20as%20a%20signed%20binary%20cache%20on%20port%208000%2C%20private%20behind%20the%20HTTPS%20proxy%0A-%20A%20nightly%20harmonia-gc%20that%20keeps%2025%25%20of%20the%20disk%20free%20and%20everything%20from%20the%20last%2014%20days%2C%20and%20Nix%27s%20own%20collection%20when%20a%20build%20runs%20low%0A-%20A%20test%20build%20on%20the%20VM%20whose%20output%20the%20cache%20serves%20with%20the%20VM%27s%20signature%0A%0ARun%20%22Set%20up%20the%20builder%22%20on%20this%20VM%2C%20skipping%20VM%20creation.%20Everything%0Ain%20%22Connect%20a%20Linux%20machine%22%2C%20%22Connect%20a%20Mac%22%2C%20%22Use%20it%20from%20CI%22%2C%20and%0Athe%20ssh-key%20and%20generate-api-key%20commands%20run%20on%20the%20owner%27s%20computers%2C%0Anot%20here.%20Don%27t%20add%20SSH%20keys%20or%20tokens%20to%20the%20owner%27s%20account%20yourself.%0AUse%20the%20official%20installer%20from%20nixos.org%20%28multi-user%2C%20--daemon%29%3B%20don%27t%0Ainstall%20Determinate%20Nix%20here.%20Install%20Harmonia%20from%20nixpkgs%20as%20written.%0ANever%20print%20%2Fetc%2Fnix%2Fcache-key.sec.%20Verify%3A%20%60nix%20store%20info%20--store%0Adaemon%60%20works%20as%20exedev%3B%20%60sudo%20-i%20nix%20config%20show%20trusted-users%60%0Aincludes%20exedev%3B%20%60curl%20-s%20localhost%3A8000%2Fnix-cache-info%60%20answers%3B%20the%0Atest%20build%27s%20narinfo%20has%20a%20%60Sig%3A%60%20line%20with%20this%20VM%27s%20key%20name%3B%0Aharmonia-gc.timer%20is%20enabled%3B%20if%20system-features%20has%20kvm%2C%20the%0Anix-daemon%20kvm.conf%20drop-in%20is%20in%20place%20and%20%2Fdev%2Fkvm%20is%20mode%200666%0Aafter%20%60sudo%20systemctl%20restart%20nix-daemon%60.%20Finish%20with%20this%20VM%27s%20CPUs%2C%20memory%2C%20and%0Afree%20disk%2C%20the%20contents%20of%20%2Fetc%2Fnix%2Fcache-key.pub%2C%20the%20builder%27s%0Asystem-features%20%28%60sudo%20-i%20nix%20config%20show%20system-features%60%29%2C%20and%20the%0Aowner%27s%20next%20steps%20from%20%22Connect%20a%20Linux%20machine%22%20and%20%22Connect%20a%20Mac%22%0Awith%20this%20VM%27s%20name%20and%20public%20key%20filled%20in.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A",
    "disk": "200GB",
    "terminal": "curl -fsSL https://exe-staging.dev/deploy/nix-builder/prompt.txt | ssh exe.dev new --disk=200GB --prompt=/dev/stdin",
    "prompt": "Set up Nix remote builder on this VM by following the exe.dev recipe at https://exe-staging.dev/deploy/nix-builder.md from top to bottom.\n\nThe recipe's example VM name is my-nix-builder. This VM's name is the output of `hostname`: use it wherever the recipe writes my-nix-builder. Skip the step that creates the VM; you are on it.\n\nThis recipe needs a 200GB disk, and a new VM's may be smaller. Before you install anything, run `df -h /`. If its size is under 180G, stop and ask me to grow the disk, either with this link: https://exe.dev/suggest?command=resize%20my-nix-builder%20--disk%3D200GB or, on my computer, with `ssh exe.dev resize my-nix-builder --disk=200GB`. When I say it's done, run `sudo resize2fs \"$(findmnt -no SOURCE /)\"`, check `df -h /` again, and carry on.\n\nYou are done when all of these are true. Check each one yourself:\n- Nix with nix-daemon, `exedev` as a trusted user, building on every core, reachable over `ssh-ng://` through exe.dev's SSH\n- A signing key made on the VM, its public key printed for clients\n- Harmonia serving the store as a signed binary cache on port 8000, private behind the HTTPS proxy\n- A nightly harmonia-gc that keeps 25% of the disk free and everything from the last 14 days, and Nix's own collection when a build runs low\n- A test build on the VM whose output the cache serves with the VM's signature\n\nRun \"Set up the builder\" on this VM, skipping VM creation. Everything\nin \"Connect a Linux machine\", \"Connect a Mac\", \"Use it from CI\", and\nthe ssh-key and generate-api-key commands run on the owner's computers,\nnot here. Don't add SSH keys or tokens to the owner's account yourself.\nUse the official installer from nixos.org (multi-user, --daemon); don't\ninstall Determinate Nix here. Install Harmonia from nixpkgs as written.\nNever print /etc/nix/cache-key.sec. Verify: `nix store info --store\ndaemon` works as exedev; `sudo -i nix config show trusted-users`\nincludes exedev; `curl -s localhost:8000/nix-cache-info` answers; the\ntest build's narinfo has a `Sig:` line with this VM's key name;\nharmonia-gc.timer is enabled; if system-features has kvm, the\nnix-daemon kvm.conf drop-in is in place and /dev/kvm is mode 0666\nafter `sudo systemctl restart nix-daemon`. Finish with this VM's CPUs, memory, and\nfree disk, the contents of /etc/nix/cache-key.pub, the builder's\nsystem-features (`sudo -i nix config show system-features`), and the\nowner's next steps from \"Connect a Linux machine\" and \"Connect a Mac\"\nwith this VM's name and public key filled in.\n\nFinish with the URLs I should open.\n",
    "prompt_url": "https://exe-staging.dev/deploy/nix-builder/prompt.txt"
  },
  "updated": "2026-11-04",
  "verified": "2026-11-04",
  "related": [
    "github-actions",
    "docker-host",
    "sandbox",
    "forgejo",
    "gitea",
    "tangled"
  ],
  "alternatives": [
    "Cachix",
    "nixbuild.net",
    "a builder in the closet"
  ]
}
