Learning Nix
solnix is built on Nix and the NixOS module system. This handbook documents what is specific to solnix — the illumos target, the package set, boot environments, SMF, the binary cache. For Nix itself — the language, the CLI, flakes, the module system — the upstream documentation is excellent and we link to it rather than duplicate it.
If you administer illumos or Solaris today with IPS / pkg, the biggest
adjustment is not the syntax — it is the shift from imperative to declarative.
This page leads with that translation, then links out to the Nix fundamentals.
(Coming from Linux/NixOS instead? See
For Linux (and NixOS) users.)
For IPS / pkg users: the mental shift
IPS is imperative and stateful. You run pkg install, pkg update,
pkg uninstall; each command mutates the live system image in place, and IPS
tracks the resulting state in its own database. The image is the accumulation of
every command you’ve ever run against it. To make that safe, IPS updates snap a
new boot environment so you can fall back if an update goes wrong.
Nix is declarative and reproducible. You do not mutate a live image. You
describe the desired system — the full set of packages and services — in a Nix
configuration, and Nix builds that description into an immutable set of
/nix/store paths, then activates it atomically. There is no accumulated
state to drift; the configuration is the system. Two machines with the same
configuration are the same system, byte for byte.
The payoff for a pkg user: the thing IPS does defensively — snapshot a boot
environment around a risky update — is the normal, every-time mode in solnix.
Every configuration change produces a new Nix generation, and solnix maps
each generation onto its own ZFS boot environment.
Rollback is not a recovery procedure; it is picking the previous BE at the
loader. IPS bolts BEs onto updates; solnix’s whole model is generations-as-BEs.
pkg → Nix, command by command
| Task | IPS / pkg (imperative) | solnix / Nix (declarative) |
|---|---|---|
| Install a package | pkg install X | add to environment.systemPackages in config → rebuild; or ad-hoc nix profile install nixpkgs#X |
| Remove a package | pkg uninstall X | remove it from the config → rebuild (it’s gone from the new generation); or nix profile remove X |
| List installed | pkg list | nix profile list, or just read the config; the store shows the closure |
| Search available | pkg search X | nix search nixpkgs X, or search.solnix.io for the solnix set |
| Update the system | pkg update (+ auto new BE) | rebuild the config → new generation → new boot environment, activated atomically |
| Roll back | beadm activate <old-BE> | beadm activate the previous generation’s BE, or pick it at the loader |
| Show/set repos | pkg publisher / set-publisher | substituters + trusted-public-keys in nix.conf → cache.solnix.io |
| Name a package | IPS FMRI pkg://.../X@version | a Nix attribute — pkgs.solnix.* (never pkgs.illumos.*) |
| Verify / fix an image | pkg verify / pkg fix | rebuild the generation — the store path is the definition, so “fix” = re-realize |
Note: the
pkgcolumn mutates one live image; the Nix column changes a description and produces a new, independently-bootable generation. You never edit the running system in place — you build a new one and switch to it.
FMRIs → attributes, publishers → substituters
Two IPS concepts map cleanly onto Nix:
- An IPS FMRI (
pkg://solaris/system/library@0.5.11,...) names a package and version in a publisher’s catalog. In solnix a package is a Nix attribute —pkgs.solnix.libc,pkgs.solnix.sys, and so on (the fine-grained illumos world; see How solnix is built). The version is pinned by the Nix expression / flake input, not resolved at install time. - An IPS publisher (a repository
pkgfetches from) maps onto a Nix substituter:cache.solnix.iois the solnix substituter, added with itstrusted-public-keysinnix.conf. Wherepkg publisherlists your repos,nix.conf’ssubstituterslists your caches — and every store path is signature-verified before use.
And the SMF story you already know carries straight over: on illumos an IPS
update reconfigures services through SMF; on solnix, services are declared with
smf.services.* and re-imported on activation. See SMF services.
Start here (Nix fundamentals)
- nix.dev — the official learning hub; tutorials from zero.
- Nix language basics — the language you write solnix configurations in.
- Nix manual —
nixCLI, the store, derivations, flakes. - Nixpkgs manual — stdenv, builders, overlays, packaging conventions.
- NixOS manual — the module system, which solnix reuses verbatim (services differ: solnix uses SMF).
- Package/options search (nixos.org) — for the upstream nixpkgs set. solnix’s own set is at search.solnix.io.
What is different in solnix
Once you know Nix, these are the solnix-specific pieces to read here:
- How solnix is built — how the illumos target is wired.
- SMF services —
smf.services.*instead ofsystemd.services.*. - ZFS boot environments — generations as BEs.
- The binary cache —
cache.solnix.io+ BitTorrent. - Package search — the package graph, backed by an EDN datom
store (
pg_mentat).
For illumos itself — the platform underneath solnix — see the illumos features overview, For Linux (and NixOS) users if you’re bridging from Linux, and Further reading & resources.
Community (Nix-wide)
solnix is a friendly neighbor in the wider Nix ecosystem:
- NixOS Discourse — the Nix community forum.
- Nix community on Matrix.
solnix’s own channels are on the Community page.