Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ jobs:
distro:
- ubuntu-v22_04
- ubuntu-v24_04
- fedora-v42-bootc
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand Down
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- install
| -------------------------------------------------------------------- | :---------------: | :---------: | :---------------: |
| Linux (`x86_64` and `aarch64`) | ✓ (via [systemd]) | ✓ | Stable |
| MacOS (`x86_64` and `aarch64`) | ✓ | | Stable (see note) |
| ostree (Fedora Silverblue, etc.) | ✓ (via [systemd]) | ✓ | Stable |
| [bootc] container images | ✓ (via [systemd]) | ✓ | Stable |
| [Valve Steam Deck][steam-deck] (SteamOS) | ✓ | | Stable |
| [Windows Subsystem for Linux][wsl] 2 (WSL2) (`x86_64` and `aarch64`) | ✓ (via [systemd]) | ✓ | Stable |
| [Podman] Linux containers | ✓ (via [systemd]) | ✓ | Stable |
Expand Down Expand Up @@ -205,6 +207,48 @@ podman rmi $IMAGE
With some container tools, such as [Docker], you can omit `sandbox = false`.
Omitting this will negatively impact compatibility with container tools like [Podman].

### On ostree-based desktops (Fedora Silverblue, etc.)

Immutable Linux distributions based on [ostree](https://ostreedev.github.io/ostree/) have a
read-only root filesystem, so `/nix` cannot be created directly. The `ostree` planner handles
this by setting up a bind mount from a persistence directory (`/var/home/nix` by default) to
`/nix` via systemd units.

On a running ostree system the installer auto-detects the right planner, so the default command
works:

```shell
curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- install
```

### In bootc container image builds

[bootc] container images are also ostree-based, but they are built without a running systemd
and without `/var` (it is created on first boot). This means the ostree planner cannot be used
during container builds. The dedicated `bootc` planner handles this lifecycle:

1. **At build time**, Nix is installed into `/nix` which becomes part of the image layer.
Systemd units, [sysusers.d](https://www.freedesktop.org/software/systemd/man/sysusers.d.html),
and [tmpfiles.d](https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html) configs
are written but no daemons are started.
2. **On first boot**, `systemd-tmpfiles` copies `/nix` to `/var/lib/nix` (mutable storage),
`systemd-sysusers` recreates the build users, and a bind-mount makes `/var/lib/nix`
available at `/nix`. The Nix daemon starts automatically.

The `bootc` planner is auto-detected when `/usr/bin/bootc` is present, or can be selected
explicitly:

```dockerfile
# Containerfile
FROM quay.io/fedora/fedora-bootc:42
RUN curl -sSfL https://artifacts.nixos.org/nix-installer | sh -s -- install bootc \
--extra-conf "sandbox = false" --no-confirm
```

> [!NOTE]
> Uninstall is not supported on bootc systems. To remove Nix, rebuild the container image
> without the `nix-installer install bootc` step.

### In GitHub Actions

[The nix installer action repository](https://github.com/NixOS/nix-installer-action/) provides a GitHub Action for installing Nix in CI workflows.
Expand Down Expand Up @@ -421,6 +465,7 @@ nix-installer uninstall /path/to/receipt.json
`nix-installer self-test` only takes [general settings](#general-settings).

[actions]: https://github.com/features/actions
[bootc]: https://containers.github.io/bootc/
[docker]: https://docker.com
[enabling-systemd]: https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/#how-can-you-get-systemd-on-your-machine
[flakes]: https://zero-to-nix.com/concepts/flakes
Expand Down
14 changes: 14 additions & 0 deletions nix/tests/container-test/bootc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM default
COPY nix-installer /nix-installer
RUN chmod +x /nix-installer/bin/nix-installer
# In a container build there is no systemd, so we use the bootc planner which
# installs Nix into /nix (part of the image layer). On first boot,
# systemd-tmpfiles copies it to /var/lib/nix and a bind-mount exposes it.
RUN /nix-installer/bin/nix-installer install bootc --logger pretty --log-directive nix_installer=trace --extra-conf "sandbox = false" --no-confirm -vvv
ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
# Verify build-time artifacts:
RUN test -d /nix/store || { echo "FAIL: /nix/store does not exist"; exit 1; }
RUN test -f /etc/sysusers.d/nix-installer.conf || { echo "FAIL: /etc/sysusers.d/nix-installer.conf missing"; exit 1; }
RUN test -f /etc/tmpfiles.d/nix-installer.conf || { echo "FAIL: /etc/tmpfiles.d/nix-installer.conf missing"; exit 1; }
RUN grep -q 'After=systemd-tmpfiles-setup.service' /etc/systemd/system/nix.mount || { echo "FAIL: nix.mount missing After=systemd-tmpfiles-setup.service"; cat /etc/systemd/system/nix.mount; exit 1; }
29 changes: 29 additions & 0 deletions nix/tests/container-test/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,35 @@ let
tester = ./default/Dockerfile;
system = "x86_64-linux";
};

# Fedora 42 WSL rootfs – used for the bootc planner container test
# (no systemd) reproducing
# https://github.com/NixOS/nix-installer/issues/155
# Re-compressed from .tar.xz to .tar.zst because podman import is
# extremely slow at xz decompression inside a VM.
"fedora-v42-bootc" =
let
xzTarball = builtins.fetchurl {
url = "https://dl.fedoraproject.org/pub/fedora/linux/releases/42/Container/x86_64/images/Fedora-WSL-Base-42-1.1.x86_64.tar.xz";
sha256 = "138vibdf0qcln3r0f116qvmq5vx8im9cy0xv2ml7r8ccsw2kvywr";
};
pkgs = forSystem "x86_64-linux" ({ pkgs, ... }: pkgs);
in
{
tarball =
pkgs.runCommand "fedora-42-rootfs.tar.zst"
{
nativeBuildInputs = with pkgs; [
xz
zstd
];
}
''
xz -dc ${xzTarball} | zstd -o $out
'';
tester = ./bootc/Dockerfile;
system = "x86_64-linux";
};
};

makeTest =
Expand Down
Loading