Persistence
Persistence Best Practices
Rules for using
environment.persistencewith impermanence without breaking NixOS activation.
The Rule
Never persist a directory that contains files created by NixOS
activation (environment.etc, home.file, home.configFile,
home.dataFile). Persist individual files instead.
Why
Impermanence bind-mounts /persist/<path> over /<path> via systemd
mount units that run at local-fs.target — before NixOS
activation. On first boot /persist/<path> is empty, hiding whatever
activation places there.
Correct (file-level)
environment.persistence."/persist".files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
];
Wrong (directory-level)
# /etc/ssh/sshd_config is a symlink created by services.openssh
# via environment.etc. The empty bind mount hides it on first boot.
environment.persistence."/persist".directories = ["/etc/ssh"];
When directory persistence is fine
Directory persistence is safe for runtime data — files created by services at runtime, not by NixOS activation:
/var/lib— service databases, state/var/log— log files/var/spool— mail, print queues- User caches:
.cache,.local/share,.local/state
These directories contain data that accumulates after boot and is never managed declaratively by NixOS.
neededForBoot and hideMounts
-
neededForBoot = true(set bypersist.nix): Ensures/persistis mounted in initrd stage 1, before the real root switches. Required for persisted files needed by early boot (SSH host keys, machine-id). -
hideMounts = true(set in each persist block): Tells GVFS to hide the mount point in file managers. Only affects desktop environments, has no effect on system behavior.
Real-world bug: SSH host keys
The modules/services/net/ssh.nix module persisted /etc/ssh as a
directory. On first boot, the bind mount hid the sshd_config symlink
that services.openssh creates via environment.etc. sshd failed with
“sshd_config: No such file or directory”.
Fix: Persist only the host key files individually. sshd_config
is a nix store symlink that doesn’t need persistence.
Real-world bug: Podman registries.conf
The modules/services/virt/podman.nix module persisted
/etc/containers as a directory, hiding registries.conf created by
environment.etc. Same pattern, same fix: remove the directory persist
since the file is NixOS-managed.