Skip to content

Repository files navigation

nixos-holochain

A declarative substrate for running Holochain edgenodes, hApps, and developer environments. Built at Sensorica, intended for the Holochain community.

Status: the modules work and are VM-tested. A conductor and its hApps come up at boot on both supported Holochain lines (0.7.0 and 0.6.3), a fleet's traffic is on a provisioned Grafana dashboard, and an HTTP gateway serves zome reads over HTTP. Fourteen NixOS VM tests run in CI. What is still open is hardware: one Holoport, sensorica-holoport-01, was installed from the runbook on 2026-09-27, and the five-machine fleet is not deployed yet (issues #8 to #12). License: MIT, the license of nixpkgs, so any module here can be reused in other flakes or proposed upstream to nixpkgs as it is. The hApps these modules run keep their own licenses (Holochain itself and Moss are CAL-1.0, hREA is Apache-2.0). Origin: Successor to the archived Sensorica/holoports-workshop, pivoting from HolOS appliance-image deployment to vanilla NixOS authorship. Documentation: the book at sensorica.github.io/nixos-holochain, built from docs/ with mdBook.


Why this exists

The Holochain ecosystem has two real deployment stories today:

  1. Dev environments via Holonix — Nix-based, well documented, mature.
  2. Production edgenodes via HolOS — a Buildroot-based appliance image you flash and run, not configure.

There is no canonical, declarative, author it yourself way to stand up a Holochain edgenode on commodity hardware. You either flash the HolOS pre-built image (without authoring the configuration) or you cobble together systemd units, conductor configs, and lair keystore management by hand.

nixos-holochain fills that gap. A flake-based repo with reusable NixOS modules so that:

  • Stewards of OVNs (Sensorica, AlterNef, others) can deploy production node fleets with a single nixos-rebuild.
  • The Holochain community gets a reference implementation for declarative edgenode hosting.
  • Workshops can teach the full stack in 4 hours instead of demoing pre-baked images.

Quickstart

One machine:

nix flake init -t github:Sensorica/nixos-holochain#minimal

That writes a flake with one nixosConfigurations.edgenode, a configuration.nix to edit and a placeholder hardware-configuration.nix to replace with nixos-generate-config --show-hardware-config from the target machine. Then:

nix flake check --no-build
sudo nixos-rebuild switch --flake .#edgenode

A fleet of five with Grafana on the first node, a Colmena hive and a live ISO:

nix flake init -t github:Sensorica/nixos-holochain#fleet

To wire the modules into a flake you already have, take the input, the holonix follows line (the module reads its default conductor and hc from inputs.holonix) and the specialArgs:

{
  inputs = {
    nixos-holochain.url = "github:Sensorica/nixos-holochain";
    holonix.follows = "nixos-holochain/holonix";
  };

  outputs = inputs @ {nixpkgs, nixos-holochain, ...}: {
    nixosConfigurations.my-node = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = {inherit inputs;};
      modules = [
        nixos-holochain.nixosModules.holochain-edgenode
        {
          services.holochain-edgenode = {
            enable = true;
            openFirewall = true;
            happs.my-app = {
              src = ./my-app.happ;
              networkSeed = "my-network-2026";
            };
          };
        }
      ];
    };
  };
}

Try it in a VM without any hardware at all:

nixos-rebuild build-vm --flake github:Sensorica/nixos-holochain#minimal-vm
./result/bin/run-*-vm

# or the observability stack, with Grafana forwarded to http://localhost:13000
nixos-rebuild build-vm --flake github:Sensorica/nixos-holochain#observability-vm
./result/bin/run-observability-vm-vm

See docs/deployment.md for the deployment guide, docs/architecture.md for how the pieces fit, and examples/sensorica-fleet/ for the worked fleet. docs/moss-node.md runs a Moss always-online node from the packaged wdocker.


Repository structure

nixos-holochain/
├── flake.nix                          # Entry point: inputs, modules, templates, packages, checks
├── modules/                           # The NixOS modules, with the exporters, recording rules and dashboards they ship
├── packages/                          # hc-http-gw per Holochain line, the conductor exporter, Moss wdocker
├── templates/
│   ├── minimal/                       # nix flake init -t …#minimal: one edgenode
│   └── fleet/                         # nix flake init -t …#fleet: five nodes, Grafana, live ISO
├── examples/
│   └── sensorica-fleet/               # The Sensorica Lab fleet: its own flake, five Holoports, ISO, Colmena hive (layout in its README)
├── tests/                             # Fixtures and the checks that need no VM
├── happs/                             # .happ bundles (not committed, see happs/README.md)
├── secrets/                           # private material only, gitignored except *.example
├── CHANGELOG.md                       # One section per release, published as its release note
├── scripts/
│   ├── changelog-section.sh           # Prints one version's CHANGELOG section
│   └── holoport-install.sh            # Erases one disk and installs a system that boots on a Holoport
├── workshop/
│   ├── facilitator-guide.md
│   ├── participant-handout.md
│   └── preflight-checklist.md
├── book.toml                          # The documentation book, built from docs/ with mdBook
└── docs/
    ├── introduction.md                # The book's first page; SUMMARY.md is its table of contents
    ├── architecture.md                # How the pieces fit, with every file under modules/ and packages/
    ├── module-options.md              # generated by `nix build .#options-doc`
    ├── deployment.md
    ├── moss-node.md                   # the Moss always-online node, as a service and by hand
    ├── releasing.md                   # How a maintainer cuts a release candidate and a release
    ├── adr/                           # architecture decision records, one per file
    ├── images/                        # dashboard screenshots
    └── archive/                       # December 2025 HolOS workshop notes

Modules

Module What it does
holochain-edgenode Conductor with an in-process lair keystore, an idempotent hApp installer, and optional Prometheus metrics. Supports Holochain 0.7 and 0.6 from one option set.
holochain-grafana Prometheus and Grafana on the monitor node, with recording rules for every state and five provisioned dashboards, each titled with its reader's question: "What is this machine running?" as Grafana's home page (each service with its state and version, each conductor with its Holochain version, each app in words), a room screen, a fleet page, a node page and an app-network page.
holochain-http-gateway hc-http-gw in front of the conductor, exposing named zome functions over HTTP. Nothing is exposed by default.
holochain-windtunnel Opt-in, off by default: joins the machine to the Holochain Foundation's Nomad cluster to run their Wind Tunnel scenarios.
holochain-bootstrap The Kitsune2 bootstrap and relay server on your own machine, so a fleet finds itself without the Foundation's test server or the internet. See Running your own bootstrap and relay.
holochain-moss-node A Moss group's always-online node as a service, beside the edgenode, with its readings and its own Grafana page. Not part of nixosModules.default, because it runs a second conductor. See docs/moss-node.md.
sensorica-event-node The Sensorica workshop's profile layered on holochain-edgenode: Holochain 0.6.3, hREA, Kando and Requests & Offers on one network seed. Not part of nixosModules.default. See examples/sensorica-fleet/README.md.

Key options for services.holochain-edgenode:

Option Default Description
enable false Enable the edgenode
package holonix holochain Holochain conductor binary; its version selects the line
hcPackage holonix hc Holochain CLI used by the hApp installer
dataDir /var/lib/holochain Persistent state directory
adminPort 4444 Admin WebSocket port
appPort 8888 App WebSocket port
happs {} hApps to install at first boot
metricsExporter.enable false node_exporter for host metrics
conductorMetrics.enable false The conductor's own holochain_* series
openFirewall false Open firewall ports

The full reference for holochain-edgenode, holochain-grafana, holochain-http-gateway, holochain-windtunnel, holochain-bootstrap and holochain-services (the list of services every module feeds to the dashboards) is docs/module-options.md, generated from the declarations by nix build .#options-doc. The Moss node's options are in docs/moss-node.md; sensorica-event-node declares none.


Tests

Fourteen NixOS VM tests, all built in CI: thirteen in the nix flake check job, and vmTestHoloportInstall in a job of its own because it copies a whole system onto a virtual disk (.github/workflows/ci.yml).

Check What it proves
vmTest / vmTest-0_6 A bare conductor comes up and answers list-apps on 0.7.0 and on 0.6.3
vmTestWithHapp / vmTestWithHapp-0_6 A hApp installs once, stays enabled, and survives a cold boot on both lines, and every one of its cells has its holochain_dht_* series on /metrics
vmTestConductorMetrics-0_6 The conductor's gauges appear on /metrics on the 0.6 line
vmTestGrafana Conductor and per-DHT series reach Prometheus, the five dashboards are provisioned with their data source and "What is this machine running?" is Grafana's home page, opening on this machine, every service its modules list carries its version, every panel query answers through Grafana's own query API (three are only required not to error: the two temperature panels, since a VM has no sensor, and "Same data everywhere", which needs two nodes), and the pages name a failed unit, a dead node and a stale, silent or unreadable conductor as such
vmTestServices / vmTestServices-noBootstrap The node page names exactly the services the enabled modules installed, each Running; a bootstrap server frozen, stopped or failing reads Not answering, Stopped or Failed, and the room screen's tile reads "A service is down"; without the server, the same list less that one
vmTestGateway A zome read answers 200 with JSON through the HTTP gateway, and a function outside the allow list answers 403
vmTestWindtunnel The generated container unit carries the flags the runner requires, and stays stopped when autoStart = false
vmTestWdocker The packaged Moss wdocker starts its pinned Holochain 0.6.1 conductor through wdaemon in an offline VM, downloads nothing into its bins directory, and wdocker stop ends the conductor
vmTestMossNode The Moss node service starts with no terminal, reads its password from a credential, survives a restart and reports holochain_conductor_up{conductor="Moss"} 1; with no password file it never starts, and an empty one is refused
vmTestBootstrap Two 0.6 edgenodes with no internet find each other through a holochain-bootstrap server and its plain-HTTP relay; its falsifier, with one node on the wrong port, must fail
vmTestHoloportInstall holoport-install lays out an empty SATA disk the ADR-017 way and installs sensorica-holoport-01 on it; the disk then boots under SeaBIOS, which is legacy BIOS like a Holoport, with GRUB for both firmwares, the conductor active and the three workshop hApps enabled once each

The checks without a VM are built in the same job: edgenodeConfigRender (relayAllowPlainText, requestTimeoutS, dbSyncLevel and wasmBackend render on each line, and that line's real conductor starts on the result), the exporter checks (conductorMetricsJq, dhtMetricsJq, metricsHelpAgreement, metricsNameShape, edgenodeNamesWiring), the Grafana checks (holochainRules, grafanaProvisioning, dashboardLabels, dashboardWords, dashboardQueries), the Moss checks (moss-dashboard, moss-names), and edgenodeBinaryCache, which nix flake check settles at evaluation.

nix flake check --no-build --all-systems
nix build .#checks.x86_64-linux.vmTestGateway -L

Workshop (Sensorica Lab, date to be fixed in #7)

This repo is the substrate for the Holochain NixOS workshop at Sensorica, the follow-up to the December 2025 HolOS/edgenode event. The exact date is issue #7.

See workshop/facilitator-guide.md and workshop/preflight-checklist.md.

Goal: Each participant deploys a working edgenode into a 5-machine fleet, watches live P2P traffic via Grafana, and rolls back a configuration change. 4 hours, no prior Nix experience required.


Contributing

See CONTRIBUTING.md. In short: open an issue first, format with alejandra, every new module ships a VM test, and regenerate docs/module-options.md in the same commit as any option change.


Roadmap

Each ticked item names the pull request that closed it.

Phase 1: the flake evaluates and the module works

  • Sensorica fleet moved to examples/sensorica-fleet with its own flake, so adopting the modules never evaluates Sensorica's machines (#13)
  • Toolchain pinned: holonix main-0.7, nixpkgs nixos-26.05 (moved from the end-of-life 25.05), committed hardware placeholders (#13)
  • CI on every push and every pull request: nix flake check plus example-fleet evaluation (#13)
  • Workshop live ISO in the fleet example, cloning the repo on first boot (#13)
  • Colmena prerequisites documented in docs/deployment.md (#13)
  • holochain-edgenode drives both Holochain lines from the real admin CLI, not from documentation (#16)
  • hApp installer verified: installs once, stays enabled, survives a cold boot (#16)
  • NixOS VM tests on 0.7.0 and 0.6.3, built in CI (#16)
  • Validated on a physical machine (#8)

Phase 2: workshop ready

  • holochain-grafana: Prometheus and Grafana with the fleet dashboard (holochain-fleet) and its data source provisioned (#17)
  • conductorMetrics: the conductor's own network stats as holochain_* series, on both lines (#17)
  • The example fleet exports metrics on all five nodes, with the Wind Tunnel runner off in writing (#17)
  • holochain-windtunnel: the Foundation's runner image, off by default, with what enabling it costs written into the option (#17)
  • Grafana dashboard screenshot in docs/images/, taken from the observability VM (#17)
  • Fleet of 5 nodes tested end to end via colmena apply (#11)
  • Workshop ISO boot-tested on target hardware (#8)
  • Five Holoports with screens, keyboards and mice at the lab (#9)
  • Dedicated router sourced and tested for P2P traffic (#10)
  • Facilitator guide reviewed with Tibi, preflight sent seven days out (#12)

Phase 3: community release

  • Flake templates: nix flake init -t …#minimal and #fleet (#18)
  • HTTP gateway module, built from tagged source per Holochain line, VM-tested (#18)
  • Option reference generated from the declarations, with a CI drift check (#18)
  • CONTRIBUTING.md with the VM-test and options-doc rules (#18)
  • hAppenings Community Substack announcement
  • hREA module (composable with the edgenode module)
  • Documentation site: the book at sensorica.github.io/nixos-holochain (#67)

Phase 4: production hardening

  • sops-nix integration for secrets
  • Lair keystore as a separate service with proper lifecycle
  • Backup and restore procedures
  • Conductor version upgrade paths

Acknowledgements

Built at Sensorica, Montreal's open value network. Successor to the December 2025 HolOS workshop organized with the Sensorica community.

About

Declarative NixOS modules for Holochain edgenodes and dev environments. Built at Sensorica.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages