···11-@document.meta
22-title: Impermanence on NixOS with ZFS and tmpfs
33-description: Guide for my impermanence setup
44-authors: [
55- ladas552
66-]
77-categories: [
88- Nix
99-]
1010-created: 2025-09-27
1111-draft: true
1212-layout: post
1313-version: 1.1.1
1414-@end
1515-* Impermanence
1616-** What is Impermanence
1717- It wipes your `/root` on reboot and your startup is a blank canvas, but you can persist mounts and bind mount directories from it in your normal root to save stuff like cache and tokens. So you wipe all the junk and save actually useful stuff.
1818-1919- For example you can install full KDE Plasma session, run it, and if you get bored. Just disable it and no KDE junk left.
2020-2121- *Important to note*: That impermanence of my setup uses tmpfs, so it writes `/root` to RAM, so nothing actually gets erased on the Disk. Meaning no continuous I/O rewrites wearing out your Drive. But the state isn't saved between reboots, as with anything on RAM
2222-2323- Also when I refer to `/root`, it's actually the whole `/`, not just root user directory.
2424-*** Why did you set it up
2525- I was bored. I don't find benefits of impermanence so crucial to completely overhaul how your system behaves and I don't trust myself to maintain it.
2626-2727- But there are some benefits to it:
2828- - I only backup important files, no cache, no states, only files and media;
2929- - I always know what's on my system because it's declared in the config;
3030- - It opens up possibilities to experiment more with my system, because if I could setup impermanence and not loose all my files, I am unstoppable;
3131-*** What's the meaning of writing this page?
3232- It's not that hard to setup impermanence, but to requires reading a lot of stuff, and if you don't use ZFS or BTRFS even full reinstall for rearranging partitions. I have read several articles, watched videos, and stole code from many GitHub repos.
3333-3434- Plus most guides just go to the wipe stage right away, without saying how to persist, or how it practically works for the user to not loose their files. I will try to compete in these aspects.
3535-3636-*** What is your current setup?
3737- I got ZFS with tmpfs, with 2 persistence datasets. /cache and /persist.
3838-3939- `/cache` is for rust targets, everything in `~/.cache`, .local states, etc.
4040-4141- `/persist` is for Media, browser profiles, Projects, etc. This is the only datasets that get's backed up by `sanoid`.
4242-4343- tmpfs is erased on reboot, so `/` and everything below it, including `/home` is gone, unless put into `/cache` or `/persist` datasets.
4444- tmpfs is on RAM, so it can overload if exceeds certain size, to prevent that I got several more zfs datasets, that aren't persisted, meaning they don't have connection to files in other datasets, but aren't erased by default.
4545-4646- `/nix` for /nix/store. I am not about to redownload all of my system on every reboot, and it also stores the generations. All the files that aren't persisted, but appear on my system are symlinked from `/nix`. That includes config files and services.
4747-4848- `/tmp` for /tmp. yeah, anyways it's to not overload tmpfs when downloading something on browser. with `boot.tmp.cleanOnBoot = true;` it is cleared on boot anyways.
4949-5050-** What we need?
5151-*** Partitions
5252- A new way to manage your system. NixOS.
5353-5454- Tho you probably already use NixOS if you are reading this, if you don't then get out while you can.
5555-5656- On a more serious note, you need ZFS setup, with 2 particular datasets.
5757- @code nix
5858- fileSystems = {
5959- "/nix" = {
6060- device = "zroot/nix";
6161- fsType = "zfs";
6262- };
6363- "/tmp" = {
6464- device = "zroot/tmp";
6565- fsType = "zfs";
6666- };
6767- };
6868- @end
6969-7070- If you don't have them, but have ZFS installed, just create them using commands
7171- @code sh
7272- sudo zfs create -o mountpoint=legacy zroot/tmp
7373- sudo zfs create -o mountpoint=legacy zroot/nix
7474- @end
7575-7676- This will insure that you won't delete your `/nix/store` and it stays intact between reboots. And for this particular setup the `tmp` dataset will be used so out `tmpfs` *root* will insure that it won't randomly overload.
7777-7878- This is a starting point, unless you have *ZFS setup* on your *NixOS* with separate datasets like that, you can kiss this Guide goodbye.
7979-8080-*** Impermanence module
8181- The [Impermanence module]{https://github.com/nix-community/impermanence} is a NixOS flake that creates `mount binds`. I still don't understand how they work, but it isn't a big idea here. The main purpose of it is to just put stuff in special `/persist` dataset, and still be able to access it from `/root` and `/home`.
8282-8383- Basically you define certain directories names in it, and it creates them, then binds them to specific relevant locations, like `".config/nvim"` will be located in `~/.config/nvim`. And if you put your Neovim config there, neovim will still follow the config, but it will be located on different dataset, and won't be wiped on boot.
8484-8585- Neat right? Not really, because if directory already exists, Impermanence will override that old directory with new empty one. *Don't panic*. Data isn't lost, it was just reallocated, you can delete the directory from impermanence module and it will comeback.
8686-8787- That's the main reason why most people reinstall their OS if they want to use Impermanence, because it's a pain in the glands to move the files from directories before persisting it and moving things back. There are projects that circumvent that, but I didn't use them. For example: [Persist-retro]{https://github.com/Geometer1729/persist-retro}.
8888-8989- Also to persist an individual file, you need to move the file, and manually copy it to persist directory.
9090-9191-**** You forgot to tell installation instructions
9292- It's nix so here is just a snippet of code. Works for flakes.
9393- @code nix
9494- #flake.nix
9595- {
9696- inputs.impermanence.url = "github:nix-community/impermanence";
9797- }
9898- @end
9999- And then just import the module, like:
100100- @code nix
101101- imports = [
102102- inputs.impermanence.nixosModules.impermanence
103103- ];
104104- @end
105105-*** Immutable users
106106- As we delete everything in `/root`, it means passwords for users, and most importantly `root` user will be deleted.
107107-108108- So just make them immutable. You can store the password file in sops, or just provide raw path from `/persist` directory.
109109-110110- @code nix
111111- # setup immutable users for impermanence
112112-113113- # silence warning about setting multiple user password options
114114- # https://github.com/NixOS/nixpkgs/pull/287506#issuecomment-1950958990
115115- # Stolen from Iynaix https://github.com/iynaix/dotfiles/blob/4880969e7797451f4adc3475cf33f33cc3ceb86e/nixos/users.nix#L18-L24
116116- options = {
117117- warnings = lib.mkOption {
118118- apply = lib.filter (
119119- w: !(lib.hasInfix "If multiple of these password options are set at the same time" w)
120120- );
121121- };
122122- };
123123-124124- config = {
125125- users.mutableUsers = false;
126126- users.users.ladas552 = {
127127- isNormalUser = true;
128128- description = "Ladas552";
129129- extraGroups = [
130130- "networkmanager"
131131- "wheel"
132132- ];
133133- initialPassword = "pass";
134134- hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
135135- };
136136- nix.settings.trusted-users = [ "ladas552" ];
137137-138138- users.users.root = {
139139- initialPassword = "pass";
140140- hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
141141- };
142142-143143-144144- };
145145-146146- @end
147147-148148- Other features for immutable users:
149149- - Can use `--no-root-password` flag in `nixos-install` command. Meaning you don't ever have to monitor it, it will install password automatically.
150150- - Can't use `passwd <user>` command. So if you mess up your password path the first time, you have to reboot to previous generation to set it correctly.
151151-152152-*** When do we start deleting stuff?
153153- Not so fast bakaru, we first need to save our stuff.
154154-155155- So you need to create persist directories