---
title: "devenv 2.4: Machines"
slug: devenv-2-4-machines
url: https://listedarticles.com/articles/devenv-2-4-machines
canonical_url: https://devenv.sh/blog/2026/09/24/devenv-24-machines/
content_type: changelog
language: en
published_at: 2026-09-24T00:00:00.000Z
updated_at: 2026-09-25T00:13:49.280Z
author: "devenv team"
authored_by: human
publisher: "devenv"
publisher_url: https://devenv.sh
topics: ["Developer Tools", "Open Source", "Infrastructure", "DevOps"]
license: all-rights-reserved
word_count: 850
reading_minutes: 4
citation: "devenv team, devenv. \"devenv 2.4: Machines.\" 24 Sept 2026. https://devenv.sh/blog/2026/09/24/devenv-24-machines/ (all-rights-reserved)"
# The full text follows. The web page shows an extract and sends readers
# to the source above; quote the citation and link the canonical URL.
---

# devenv 2.4: Machines

> devenv 2.4 adds Machines: declare NixOS (and other) host configs beside your nix-based dev environment, then build, install, and deploy with devenv machines.

# devenv 2.4: Machines

devenv 2.4 introduces Machines.

Define machine configurations alongside your development environment, then build and deploy them with `devenv machines`.

It supports:

You can contribute support for another OS to Machines.

SecretSpec can provide the credentials a new NixOS host needs on its first boot.

Machines are experimental, and we’d like feedback from people using it on real hosts.

## From a development environment to a machine

For a NixOS server, add the disk and hardware detection inputs:

Then declare the machine in `devenv.nix`:

The imported NixOS module can define services, users, a bootloader, and a disk layout. devenv wires in disko and nixos-facter. On first install, it saves the host’s hardware report to `.machines/server/facter.json`. Commit that file so others and CI can build the configuration. See the disk layout example before installing.

Inspect or build a machine without contacting its target:

`info` lists systems, targets, and roles. `build` realizes all roles for `server` so you can check or cache them before deploying.

## Install a new NixOS host

Run:

devenv connects over SSH, enters a NixOS installer with kexec, collects hardware facts, and builds the system **before** changing disks. If the build succeeds, it runs disko, installs the system, and reboots.

You must name each machine. Installation partitions and formats disks without prompting, so check the SSH target and disko disk paths first. Use stable `/dev/disk/by-id/` paths instead of names such as `/dev/sda`. You can install multiple hosts and limit concurrency with `--max-concurrent`.

See installation options and preflight requirements for encryption keys, extra files, and SSH host key preservation.

## Bootstrap secrets with SecretSpec

A new host may need a secret before sops-nix can start, such as an age identity. Declare it in `secretspec.toml` and map it to a file in the installed system:

In `./nixos/server.nix`, set `sops.age.keyFile = "/var/lib/sops-nix/key.txt";` to use the file on first boot.

With `execution = "target"`, the live installer resolves the secret through its own SecretSpec provider and writes the file after `nixos-install`, before reboot. The workstation sends the declaration, not the secret or provider credentials. The provider must work in the live installer, for example through instance identity. This mode does not require `secretspec.enable` in `devenv.yaml`.

The default `execution = "local"` resolves secrets on your workstation and sends them over SSH. This requires trusting the target’s SSH host key in advance. Neither mode puts secret values in the Nix store. Bootstrap files are written only during `machines install`; use sops-nix or agenix for later rotation. See bootstrapping from SecretSpec for provider setup and transfer details.

## Review a deployment before it changes anything

Use `check` to review SSH access changes without building, or `deploy` to build, review, and apply a NixOS system:

`deploy` compares the build with the running generation and shows closure and access changes. It blocks configurations that disable SSH or root login and warns about changed ports or administrator keys. External firewalls still need your review.

To review now and deploy later, save a plan:

`apply` uses the planned outputs without rebuilding and rejects a stale plan if the target or NixOS generation has changed. For multiple targets, it prepares all of them before activating any. Both `deploy` and `apply` require confirmation unless you pass `--yes`.

## Recovery runs on the NixOS target

NixOS activation runs in a systemd service on the target, under a deployment lock. A watchdog restores the previous system if activation or a health check fails, or if devenv cannot confirm success before the deadline. It can also recover an unconfirmed deployment after reboot, once NixOS reaches userspace.

Configure an application health check in `devenv.nix`:

The default deadline is 300 seconds. Without a custom health check, devenv checks only the system paths. If your connection drops, check the outcome before retrying. Use `rollback` if you need to switch to the previous recorded system:

Recovery requires the target to reach userspace with its previous store paths and state intact. It cannot fix early boot failures or undo application data changes.

## One plan for a mixed fleet

One machine can combine NixOS or nix-darwin with home-manager. With no machine names, `deploy` selects every SSH target and reviews the fleet together:

Every role is built, and remote outputs are copied, before activation begins. Machines activate one at a time in name order by default. `--max-concurrent` activates batches; after a failure, no new batches start, but successful machines stay deployed.

Within a machine, home-manager activates after the system role. NixOS has automatic rollback; nix-darwin and home-manager do not. A failed home-manager activation leaves an already confirmed NixOS deployment in place.

With the C-Nix backend, `--use-machines-as-builders` makes declared SSH targets available as remote builders for cross-platform deployments.

## Other fixes since 2.3

devenv 2.3.1 restored public signing key fetching for `cachix.pull` caches and removed duplicate cache entries. This release also fixes quoted `devenv shell` commands, a crash when its terminal closes, and `devenv lsp` startup aborts. See the changelog for the full list.

See the Machines guide for configuration and operational details.

If you try Machines, tell us how it goes in a GitHub issue or on Discord.

Domen
