# I am confused about the reproducibility of a system through flakes

**URL:** https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974
**Category:** Help
**Created:** [July 16, 2026, 7:44am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974 "2026-07-16T07:44:23Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![danielo515](https://discourse.nixos.org/user_avatar/discourse.nixos.org/danielo515/32/31112_2.png) [@danielo515](https://discourse.nixos.org/u/danielo515)
#### Post date: [July 16, 2026, 7:44am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/1 "2026-07-16T07:44:23Z")

</div>

Sorry if the title is not very clear. I was not sure how to summarize my doubt in a single sentence that made sense.

I’m looking for an explanation on the philosophy behind having your system configurations as a flake stored in a git repository so you can track your changes and do your “configuration as code” and start “treating your machines as cattle” thingy.

So far, I have only used Nix for defining my macOS configurations, and to be honest, I never used my two Mac machines as daily drivers at once. I always stick to one of them and keep iterating my configuration on that single machine.

The idea was to expand my flake into a kind of all-my-systems store, including some VMs of my home lab, so I don’t have to take notes on how to get some VMs back to the intended state.  
The idea is that I can have everything in my repository, and all that they need when I get a new laptop or a new whatever is just to use my flake to set everything up. That is the goal, and that is what attracted me to Nix.

However, every time I check how to set a new NixOS machine to use your flake (which I haven’t done yet) I am greeted it with some steps that, in my opinion, go against this philosophy. You are supposed to:

1. Set a new NixOS machine.
2. Copy that specific machine’s hardware configuration into your flake.
3. Store that hardware configuration into your flake.

How is that reproducible? What if I spin up another VM that I want to be exactly the same configuration, but I prefer to use a different network card, or I wanted to have two network cards? Then my Nix configuration, which is only focused on user-land things, will need a new hardware definition added to my flake? This part is what confuses me and makes me think that this is not the right way to “treat your hosts as cattle”. It feels more like “have a spreadsheet with all your pets” to me.  
This gets even more confusing if you decide to use an actual physical machine, where the hardware will be very specific to that machine. If you then decide to change it because, let’s say, your actual physical machine broke, you will have to modify the hardware section of your flake to accommodate your new machine?

Can someone clarify me if people use nix and then keep a curated set of pets? Or how does people do this?

---

<div class="post-metadata">

### Author: ![andrewzah](https://discourse.nixos.org/user_avatar/discourse.nixos.org/andrewzah/32/38182_2.png) [@andrewzah](https://discourse.nixos.org/u/andrewzah)
#### Post date: [July 16, 2026, 8:26am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/2 "2026-07-16T08:26:28Z")

</div>

I’m not any expert by any means, but you don’t have to do that flow of install nixos → generate hardware-configuration → copy to flake.

You can use something like [nixos-anywhere](https://github.com/nix-community/nixos-anywhere), with [disko](https://github.com/nix-community/disko) to handle disk partitioning. That’s what I did when I set up a NixOS VPS with Hetzner. That system lives in [my “homelab” flake](https://git.bebop.lol/bebop/nix-homelab/src/branch/master/hosts/deejay/default.nix), which effectively now is a “all-my-servers” flake.

> How is that reproducible? What if I spin up another VM that I want to be exactly the same configuration, but I prefer to use a different network card, or I wanted to have two network cards? Then my Nix configuration, which is only focused on user-land things, will need a new hardware definition added to my flake? This part is what confuses me and makes me think that this is not the right way to “treat your hosts as cattle”. It feels more like “have a spreadsheet with all your pets” to me.

There’s no getting around adding machine-specific hardware modules. But yeah, you’d just update hardware-configuration.nix or wherever appropriate in that host’s config. You could also extract out logic into a module.

Does that help answer your question? I maintain a couple laptops and ~six or so servers with NixOS, so I can answer some questions around deployment.

---

<div class="post-metadata">

### Author: ![frost](https://discourse.nixos.org/user_avatar/discourse.nixos.org/frost/32/32959_2.png) [@frost](https://discourse.nixos.org/u/frost)
#### Post date: [July 16, 2026, 8:49am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/3 "2026-07-16T08:49:40Z")

</div>

Note that another sense of “reproducibility” w/rt flakes comes from purity.

Pre-flakes, the intended way to manage a system’s version of nixpkgs was with channels, which were stateful per-device. Hence, the same config on two devices could produce different results by virtue of using different versions of `nixpkgs`.

A flake-based config, by describing and locking its `inputs`, is (in theory) wholly reproducible from just the flake itself, with no per-system state. This purity can be violated by, for example, having a relative local path as an input, but for the most part the idea that “the flake is a self-contained description of the entire system” holds.

Such reproducibility can be achieved without flakes with tools like `npins`, which serve a similar “describe and lock dependencies” purpose. However, flakes come with purity enforced by default, while there is (to my knowledge) no such enforcement available without flakes.

One other thing to address is the strict meaning of “reproducible” w/rt Nix. While Nix is meant to (and often does) make replicating a configuration on a new device easy, “reproducible” is moreso in a functional sense. Derivations, by specifying expected hashes for their requirements (such as downloaded source code), and being built in isolated environments, should be bit-by-bit reproducible, such that two people building the same version of the same package can reproduce the exact same result (ignoring, for example, `-march=native` optimisation or similar hardware-linked variance).

This sense of reproducibility is why, for example, Guix is so valuable for the scientific community. I can publish a derivation for the code used by [whatever paper] with the understanding that another Guix user can (in theory) exactly reproduce my results.

---

<div class="post-metadata">

### Author: ![bme](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@bme](https://discourse.nixos.org/u/bme)
#### Post date: [July 16, 2026, 9:30am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/4 "2026-07-16T09:30:23Z")

</div>

As with all things there is a spectrum. I guess I don’t understand what a cattle nixos looks like on diverse hardware? If you have a different disks on each computer, different cpus etc, how do you think that should look? It’s very easy to go full cattle on AWS for instance, but even then: you can have instances with local block devices, multiple attached ebs volumes, extra nics. You manage that typically by injecting metadata about the hw into your config (for instance I manage all vms with terraform, and inject json into the userdata script that nixos modules read to configure themselves). The nixos installer hardware scan effectively does that on your local hardware, but it’s not the only way to do things. If you have an identically labelled set of hard drives on all your computers, you can keep that as shared. If you only use the same CPU family, again all shared. You can even reject nixos modules that depend on hardware, and your create your own that can do more dynamic setup, s.t. that if you have a kernel with the superset of modules you need, then udev rules + systemd can do setup on the fly.

Also see [facter](https://github.com/nix-community/nixos-facter) for another take on solving this.

The world is your oyster, and with nix shall you open it.

---

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [July 16, 2026, 10:41am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/5 "2026-07-16T10:41:34Z")

</div>

> [@danielo515](#):
>
> Can someone clarify me if people use nix and then keep a curated set of pets?

In practice, I think what’s confusing you is that the answer to this is largely “yes”.

If you’ve heard people referring to their personal devices as “cattle”, that is because they don’t understand the pets vs cattle analogy.

NixOS is however _very_ good at declaratively describing pets, to the point that managing their similarities and dissimilarities becomes feasible.

Most of this power comes from the module system - if you learn to use it, you can create some wicked maintainable pets.

Swapping out some hardware config while maintaining more interesting software config identically is trivial, and both hardware setups can be maintained alongside each other in the same codebase without interfering, at any level of granularity. If you haven’t played around with `lib.mkForce`, or noticed the merge rules for e.g. `types.listOf`, you’ve probably not fully realized the implications of NixOS’ module system design - it really is a huge part of what makes the nix ecosystem so good at what it does.

Of course, if your laptop gets stolen, you’ll have to buy a new laptop and do some manual provisioning steps. This is the hallmark of a “pet” - however, a good NixOS config _does_ limit this provisioning to only configuring things bespoke to this pet, rather than the full OS, which makes it significantly more achievable - especially if you use e.g. [preservation](https://github.com/nix-community/preservation) to minimize drift. Still a pet, but it’s like you got an automated feeder.

Full “cattle”-style configuration is of course feasible, but you’ll have to lean heavily on systemd and networking features, and actually provision at least similar hardware (and write a custom installer). This is not what people do in their homelabs.

All of this has almost nothing to do with flakes, reproducibility, or even nix itself, it’s all developed in NixOS. All those properties just help upstream develop and maintain NixOS in the first place, end users can ultimately largely ignore that stuff and still get benefits from NixOS as a deployment tool.

I believe that this is why weird warts are so common in random configurations; people often don’t understand what they’re breaking (or sometimes just don’t care in the short term), and the results are often not immediately visible.

> [@frost](#):
>
> However, flakes come with purity enforced by default, while there is (to my knowledge) no such enforcement available without flakes.

That’s a misunderstanding of “pure eval”. Pure eval means that your nix code will be evaluated from within the nix store.

Without pure eval your nix files are allowed to be anywhere, but the resulting deployment script is still generated with functional “purity” - you get fully reproducible results.

---

<div class="post-metadata">

### Author: ![frost](https://discourse.nixos.org/user_avatar/discourse.nixos.org/frost/32/32959_2.png) [@frost](https://discourse.nixos.org/u/frost)
#### Post date: [July 16, 2026, 11:03am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/6 "2026-07-16T11:03:11Z")

</div>

> that’s a misunderstanding …

Interesting, thank you for the correction. Perhaps I articulated myself poorly - my understanding was that arguments like `--impure` for `nixos-rebuild` were for flakes only, and that there was no way to achieve pure eval w/out using flakes (indeed, I’ve definitely done some impure evals w/ my flakeless setup, for example when using npins environment variables).

Do you know of a way to perform pure eval of a non-flake config (using, eg., part of the nix3 CLI)?

---

<div class="post-metadata">

### Author: ![nrabulinski](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nrabulinski/32/10857_2.png) [@nrabulinski](https://discourse.nixos.org/u/nrabulinski)
#### Post date: [July 16, 2026, 12:02pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/7 "2026-07-16T12:02:05Z")

</div>

You technically can, but not really no. This is one of the big gripes with flakes, and why people so often say that they have features unnecessarily tied to them, which could benefit the greater Nix ecosystem.

---

<div class="post-metadata">

### Author: ![zwol](https://discourse.nixos.org/user_avatar/discourse.nixos.org/zwol/32/31829_2.png) [@zwol](https://discourse.nixos.org/u/zwol)
#### Post date: [July 16, 2026, 1:17pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/8 "2026-07-16T13:17:32Z")

</div>

Even in an environment that’s as “cattle” as it can be, there’s a few files that _must be_ unique to each host, such as `/etc/machine-id` and the SSH host keys. And, if you want to be able to move an existing host to new (matching) hardware 100% seamlessly – which, as I understand it, is a big piece of the _point_ of “cattle” configuration management – you have to have those files be part of the system derivation somehow.

(In my own system derivations I go out of my way _not_ to derive SOPS machine keys from SSH host keys, for this exact reason. I don’t understand why all the guides tell you to do that. Yes, it avoids a difficult and poorly automated key management step, but it’s setting you up for a catastrophe later.)

---

<div class="post-metadata">

### Author: ![withakay](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/w/f475e1/32.png) [@withakay](https://discourse.nixos.org/u/withakay)
#### Post date: [July 16, 2026, 1:55pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/9 "2026-07-16T13:55:22Z")

</div>

> [@frost](#):
>
> Derivations, by specifying expected hashes for their requirements (such as downloaded source code), and being built in isolated environments, should be bit-by-bit reproducible, such that two people building the same version of the same package can reproduce the exact same result (ignoring, for example, `-march=native` optimisation or similar hardware-linked variance).

Bit-for-bit reproducibility is a very high bar, and while projects like [https://reproducible.nixos.org/](https://reproducible.nixos.org/) attempt to tackle this and binary caches can hide/mitigate/shim bit-for-bit-style reproducibility, the use of nix alone is not sufficient to claim bit-for-bit style repro, especially because many build chains and software are not written to be easily bit-for-bit repro. See ["NixOS is not reproducible"](https://discourse.nixos.org/t/nixos-is-not-reproducible/42688) for more details and perhaps a better place to actually have the discussion if more commentary is important. I’m only commenting in this thread because I think as a community it does a disservice to advertise claims that later do not prove out. That can cause a lot of loss of faith in the ecosystem.

Nix does provides dependency-graph reproducibility, as you note, which is already great for most practical purposes and very hard to achieve in other ecosystems. A great win! Definitely a huge reason to use nix, and I don’t see a better tool currently.

---

<div class="post-metadata">

### Author: ![fricklerhandwerk](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fricklerhandwerk/32/2029_2.png) [@fricklerhandwerk](https://discourse.nixos.org/u/fricklerhandwerk)
#### Post date: [July 16, 2026, 2:30pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/10 "2026-07-16T14:30:26Z")

</div>

> [@frost](#):
>
> there was no way to achieve pure eval w/out using flakes

Just don’t use impure language constructs, in particular `<…>` [lookup paths](https://nix.dev/manual/nix/latest/language/constructs/lookup-path.html).  
This is exactly what [`--pure-eval`](https://nix.dev/manual/nix/latest/command-ref/conf-file#conf-pure-eval) will enforce in addition to closing down network access.

In practice it’s often convenient to have some controlled impurity though, for instance `toString ./some/file` for local helper scripts or (rarely) passing `builtins.currentSystem` at entry points.

> [@frost](#):
>
> Pre-flakes, the intended way to manage a system’s version of nixpkgs was with channels, which were stateful per-device.

This only half true, i.e. the worst kind of wrong, and a misunderstanding that keeps getting perpetuated. Yes it was originally intended like that, but in _ancient times_. Nobody would seriously have suggested doing that in say 2017.

[Channels](https://nix.dev/manual/nix/latest/command-ref/nix-channel) are a distribution format for Nix expressions (a directory with particular things in it, including a Nix expression), are still being produced by Hydra, in practice have persistent identifiers ([example](https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1035098.35d3407a3816)), can still be consumed by flakes, and are only problematic when references to them are managed outside of expressions.

So what _beginners_ indeed often did in the distant past — due to lack of well-documented and easy-to-find alternatives — is use `nix-channel --update` which would download a channel `foo` to some file, and then refer to it as `<foo>` in their expressions. This of course would fall apart on the next machine which may not have that downloaded channel at all, have it downloaded at a different time and thus have a contents, or get out of sync on the next `nix-channel --update`. After a while people would figure out a still barely documented fact: when building a channel from a release branch is done, Hydra pushes the respective commit back to a Nixpkgs branch corresponding to that channel (which a while ago we decided to call [channel branch](https://nix.dev/concepts/faq#which-channel-branch-should-i-use) and at least finally wrote that down somewhere). One can just download the tarball of that commit from GitHub with `builtins.fetchTarball` with a hash, and even the URL is stable. [`npins`](https://github.com/andir/npins) just automates the boilerplate around storing those references in a JSON file and fetching the latest commits.

So in fact, combining `npins` and `--pure-eval` gives you that purity part.

Flakes add a bunch more stuff, such as caching evaluation of top-level attributes and hard-wiring the semantics of some of them into CLI commands such as `nix flake check` and `nix run`. The latter can also be done with a combination of classic commands, very light scripting, and the module system (which is slower to evaluate but gives you a rather strong type system and the associated machinery to automatically check your expressions for consistency).

---

<div class="post-metadata">

### Author: ![pr06lefs](https://discourse.nixos.org/user_avatar/discourse.nixos.org/pr06lefs/32/2729_2.png) [@pr06lefs](https://discourse.nixos.org/u/pr06lefs)
#### Post date: [July 16, 2026, 2:32pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/11 "2026-07-16T14:32:12Z")

</div>

I’m not sure I understand what you want to happen. If you have a machine with one network card and one with two, and you want to use the same configuration for both, how do you expect to use the second network card?

If you’re using by-uuid identifiers for your hard drives, your hardware-configuration.nix will never be identical for any two machines. But you can share other configuration between them through imports, like for instance your list of installed packages.

Maybe what you want is some way to automatically generate a hardware-configuration.nix per machine, according to some rules?

---

<div class="post-metadata">

### Author: ![ElvishJerricco](https://discourse.nixos.org/user_avatar/discourse.nixos.org/elvishjerricco/32/984_2.png) [@ElvishJerricco](https://discourse.nixos.org/u/ElvishJerricco)
#### Post date: [July 16, 2026, 5:33pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/12 "2026-07-16T17:33:02Z")

</div>

> [@pr06lefs](#):
>
> If you’re using by-uuid identifiers for your hard drives, your hardware-configuration.nix will never be identical for any two machines.

For the record, this is sort of why I don’t actually consider using UUIDs for disks to be the best idea in a lot of cases. It’s probably still the best _general purpose_ recommendation, but it does fundamentally mean things aren’t generic. Or, to put it another way: UUIDs are state, not configuration. Sometimes state leaks into configuration, and that’s ok, and NixOS at least makes that very explicit. But in terms of having really generic logic in your nix code, there’s a strange link between eval/build-time and runtime information. For the eval/build-time code to be generic, the runtime code has to be generic as well; we can’t make a NixOS module that detects your hardware needs automatically because that would be impure. And making the runtime logic generic is where it gets stateful. e.g. NetworkManager discovering NICs and managing them statefully, or other distros probably consider `/etc/fstab` to be _state_ rather than config like NixOS does, but those both still rely on generic runtime components, namely the kernel being capable of arbitrary NIC and FS drivers.

One of the options for a generic config that doesn’t have UUIDs is `boot.initrd.systemd.root = "gpt-auto";`, which causes the root FS and ESP to be found at runtime based on which device the system booted from in the first place. Conceptually, this is much cleaner logic, because at the end of the day the intent is just to get the system to boot with the right FS, not to use a specific UUID; what exactly that FS _is_ can’t really be explained by a UUID, so `gpt-auto` instead imposes rules on the boot disk formatting and uses those rules as the definition of the root FS. It shifts the partition discovery logic into a stateful system instead of a configuration system, which I think is broadly the right move for a lot of cases. If you don’t want to use `gpt-auto` (its partitioning rules _are_ kind of restrictive), I think using `by-label` is pretty similar in spirit; the _state_ is “which device has the designated label?”, and the configuration is just the search for that label. I think this is more fraught than `gpt-auto`, because `gpt-auto` only requires _the boot disk_ to be formatted a certain way, while `by-label` requires _all disks_ to avoid using that label unless it’s the intended partition. But it’s a useful approximation, and I’d be interested in exploring more complicated options in this area.

I do also want to mention an interesting hybrid that sits between the “partitions as state” and “partitions as config” ideas, which is `dm-verity` and the `roothash=` kernel param. The premise here is somewhat more generic than `gpt-auto` and has no interest in whether the root FS is on the same disk as the ESP. The `roothash=` param specifies an immutable, content-addressed partition pair. That hash is the root hash of a `dm-verity` merkle tree, and instead of generating random UUIDs for the data and verity partitions, the hash is used; the first 128 bits of the hash get stored as the UUID of the data partition, and the last 128 bits get stored as the UUID of the verity partition. At runtime, the OS doesn’t need any stateful information at all; the `roothash=` is _configuration_, because it only specifies the cryptographic identity of the OS to boot. That directly tells it what UUIDs to search for, and it doesn’t matter what stateful partitions get found because `dm-verity` will transparently ensure that all the data that’s accessed matches the `roothash=`.

Anyway, the big point here is just that generic configs _are_ possible, if you figure out how to separate the state into runtime logic. The most obvious options include `gpt-auto` and `by-label`, but that’s only for the FS. For networking, there’s `NetworkManager` (which has reasonable default behaviors for generic circumstances). For the actual _storage drivers_ that the FS depends on (like `nvme` and stuff like that, which the initrd needs to have for the FS to even be visible), there’s the `hardware.enableAllHardware` option that just adds a bunch of them in hopes it covers everything. I think generic configs seem like a pretty good idea a lot of the time, and I think separating your stateful information from your config is good in general. But certainly it’s not really the norm right now.

---

<div class="post-metadata">

### Author: ![llakala](https://discourse.nixos.org/user_avatar/discourse.nixos.org/llakala/32/38325_2.png) [@llakala](https://discourse.nixos.org/u/llakala)
#### Post date: [July 16, 2026, 8:04pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/13 "2026-07-16T20:04:55Z")

</div>

> [@fricklerhandwerk](#):
>
> The latter can also be done with a combination of classic commands, very light scripting, and the module system (which is slower to evaluate but gives you a rather strong type system and the associated machinery to automatically check your expressions for consistency).

Why would you need the module system for a `nix run` equivalent? Isn’t a `callPackage` set more idiomatic?

---

<div class="post-metadata">

### Author: ![withakay](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/w/f475e1/32.png) [@withakay](https://discourse.nixos.org/u/withakay)
#### Post date: [July 16, 2026, 10:12pm UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/14 "2026-07-16T22:12:43Z")

</div>

Pretty sure “the latter” is referring to

> [@fricklerhandwerk](#):
>
> hard-wiring the semantics of some of [the flake top level attributes] into CLI commands

---

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [July 17, 2026, 2:32am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/15 "2026-07-17T02:32:38Z")

</div>

I just want to add in addition to what @fricklerhandwerk says:

Pure eval, as implemented with flakes today, is one of the big misfeatures of the flake-guarded features. It’s implemented by copying your repositories into the store wholesale, any time you evaluate them after you make a change, and results in huge performance overheads, alongside security risks and - more relevantly today - SSD wear.

And as @fricklerhandwerk says, most of what it does is just turn off certain built-ins and language constructs that could be prohibited by a linter.

It’s mostly implemented this way because _technically_ you could end up encoding the absolute path of a file during eval. This, too, could probably be prohibited differently. It really pains me that this feature is so terribly implemented, the idea makes a ton of sense, but thanks to how it works it’s most of what is wrong with flakes IMO.

---

<div class="post-metadata">

### Author: ![danielo515](https://discourse.nixos.org/user_avatar/discourse.nixos.org/danielo515/32/31112_2.png) [@danielo515](https://discourse.nixos.org/u/danielo515)
#### Post date: [July 17, 2026, 6:36am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/16 "2026-07-17T06:36:38Z")

</div>

> [@andrewzah](#):
>
> Does that help answer your question? I maintain a couple laptops and ~six or so servers with NixOS, so I can answer some questions around deployment.

Yes, it gives me some “links” to follow, but I would like to know what is your flow.  
Can you give me a numbered list of the steps you usually follow? Let’s say you want a new hetzner server, what do you do after purchasing it?

How is the flow with the laptops? Let’s say you get a new one for a new company you will be working for

---

<div class="post-metadata">

### Author: ![danielo515](https://discourse.nixos.org/user_avatar/discourse.nixos.org/danielo515/32/31112_2.png) [@danielo515](https://discourse.nixos.org/u/danielo515)
#### Post date: [July 17, 2026, 6:51am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/17 "2026-07-17T06:51:41Z")

</div>

> [@pr06lefs](#):
>
> I’m not sure I understand what you want to happen. If you have a machine with one network card and one with two, and you want to use the same configuration for both, how do you expect to use the second network card?

That’s because I don’t expect nix to take care of the specific parts of that host, or at least not my “curated” config.  
I want my config to be about users, services, binaries, and user configurations. I don’t want to maintain a repository of hardware configurations. For me that is OK to live in each host as part of the “snowflake”.

So my understanding is that I have to start the basic system with some other tool (like cloud-init for example) then clone my flake and “apply it”.  
That simple sentence I have no idea how to do in the most possible automatic fashion.

And also, I was wondering if it is possible to use Nix or NixOs for the entire thing, rather than having to use terraform + ansible + nix or something like that

I’m all questions

---

<div class="post-metadata">

### Author: ![Mapybara](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/8dc957/32.png) [@Mapybara](https://discourse.nixos.org/u/Mapybara)
#### Post date: [July 17, 2026, 6:56am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/18 "2026-07-17T06:56:12Z")

</div>

> [@danielo515](#):
>
> I want my config to be about users, services, binaries, and user configurations. I don’t want to maintain a repository of hardware configurations.

The big thing about NixOS is that it manages not only binaries and services but also the kernel. (It doesn’t actually manage user configurations in detail - it does a bit, but for a lot of things you need something like Home Manager, which is separate, or else use normal vanilla-linux-type configuration files.) Because it manages the kernel, it needs to know all about your hardware. If you don’t want that then you don’t want NixOS, although you may still want nix, which you can use on top of any linux.

---

<div class="post-metadata">

### Author: ![Mapybara](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/8dc957/32.png) [@Mapybara](https://discourse.nixos.org/u/Mapybara)
#### Post date: [July 17, 2026, 6:57am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/19 "2026-07-17T06:57:35Z")

</div>

> [@danielo515](#):
>
> And also, I was wondering if it is possible to use Nix or NixOs for the entire thing, rather than having to use terraform + ansible + nix or something like that

With NixOS yes, with just nix no.

---

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [July 17, 2026, 7:08am UTC](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974/20 "2026-07-17T07:08:05Z")

</div>

> [@danielo515](#):
>
> I don’t want to maintain a repository of hardware configurations. For me that is OK to live in each host as part of the “snowflake”.

@ElvishJerricco sketches how you could avoid this. `hardware-configuration.nix` very rarely contains anything super important (except perhaps the `system` tuple, but you can solve that by only maintaining one architecture per configuration or somesuch).

It’s similar to the idea of `cloud-init`, but `cloud-init` itself is a bit too focused on fhs-compliance, so hand-rolling your own dynamic config tends to be a bit better.

I do recommend starting out with per-host `.nix` files that isolate the “snowflakey” bits, though, and then just slowly getting rid of each option in them one-by-one.

[Next page](https://discourse.nixos.org/t/i-am-confused-about-the-reproducibility-of-a-system-through-flakes/78974.md?page=2)
