I am certain that this question has been asked a million times by insufferable newcomers. However, I’ve been utterly unable to locate this basic information.
As an example:
Ad hoc shell environments — nix.dev documentation explains how to perform most functions via the shell, rather than via the configuration file. I’ve been unable to locate any section within which it elaborates on what I care about.
nixos-generate-config doesn’t appear to function, despite this command supposedly being necessary to generate the files:
[rokejulianlockhart@nixos:~]$ nixos-generate-config
writing /etc/nixos/hardware-configuration.nix...
write_file '/etc/nixos/hardware-configuration.nix' - sysopen: Permission denied at /run/current-system/sw/bin/nixos-generate-config line 662.
I am hesitant to invoke it as UID0, for it might overwrite something which exists. I’d rather not reimage my VM.
I’m searching for this information irrespective of any dependent knowledge of how to utilize the OS because that’s the function for which I’m evaluating the OS in a VM - I want to know what Nix’s configuration file syntax is like.
If you mean the file to use as an entry point for evaluating a NixOS configuration:
It doesn’t matter where you put that file, but nixos-rebuild defaults to assuming /etc/nixos/configuration.nix, which can be changed by adding -I nixos-config=/path/to/config.
I don’t know where this convention originated, and can only speculate it might have come from following historical ideas how things are done. These days, being thoroughly immersed in a nixified worldview, I think it’s an antipattern to store anything outside one’s user directory.
The problem is that changing the tooling defaults is very hard to do elegantly and without disruption — it’s easier to build alternative tools to change defaults. But building entire tools is more expensive overall for multiple reasons, especially if one wants to also cater to existing users.
I’d like to spread ideas on how to think about things differently by changing the right spots in documentation and such conversations, because I hope that this will make designing new tools much more straightforward and much easier to find adoption for.
Also it’s completely independent of the shell environment feature, which can be used on any Linux and macOS.
Not sure what you’re asking for exactly but “the” config can be stored anywhere, you can even have multiple configs (and don’t let me start on Flakes) but the config itself isn’t really important, the system, once built, doesn’t refer to or store the input config anywhere.
Think Dockerfile.
As for nixos-generate-config, that one only makes sense to run when bootstrapping, it detects mountpoitns and creates the initial hardware-configuration.nix input so the system can boot. You shouldn’t need to run it on an already bootstrapped system.
/etc is generally only writable by root, you can try changing the perms of /etc/nixos/ but I wouldn’t particularly recommend that since you’re configuring the entire system with what it generates, and you may not want those files world-writable. Well, depends on your threat model, I guess. Alternatively you can use --root like its manpage indicates if you want to put the files elsewhere, though that also affects mounts in the NixOS config.
@fricklerhandwerk, that configuration file appears to include a fair bit more than what nixos-generate-config creates. I’m guessing that that’s because it’s what was used to generate the system, whereas the user-created one only needs the bare minimum because it’s applied afterward (if that makes sense)?
@jficz, /etc/nixos/configuration.nix exists. However, I was confused due to the absence of the --dir flag - I expected that it was failing because a file already existed that it didn’t want to overwrite.
I’m trying to create an initial configuration file as a new user, so that I can evaluate how Nix’s fabled reproducible configuration system works. Is this not the method to accomplish this?
@waffle8946, indeed. Though, in retrospect, I’m rather glad I didn’t, for I might have overwritten /etc/nixos/configuration.nix if I had stupidly tried the --dir flag simultaneously.
Nix, but I’m going to use NixOS to evaluate it, since that’s going to yield the best results, I imagine?
Nix doesn’t care what distro you use, I’m just trying to verify the question you’re asking.
Because you say it’s a “nix” config but you mention /etc/nixos/configuration.nix, which is the default entry point of the NixOS config. Of course you can relocate said files as you please.
I’m not sure what you believe “reproducible” means - it means same inputs → same outputs (roughly), which implies no side inputs or effects. Obviously that’s not possible when deploying a configuration, so NixOS is by nature not reproducible. And then you also talk about nixos-generate-config, which is another topic entirely, it’s a perl script which generates nix code which is used to configure NixOS, which of course has even less such guarantees.
Even the packages in the minimal NixOS iso are not 100% reproducible, though it’s of course an overall goal, nix simply shells out to other build systems whose reproducibility is really dependent on how the upstream projects structure their build.
So practically, things built by nix are not reproducible, this is a common misconception.
Based on these misunderstandings it’s even less clear to me what your goal is. If it’s to learn how to configure NixOS, I’d say start with the NixOS manual. There’s also the nixpkgs manual for explaining how to work with the repository of packages, and the nix reference manual for how to use the Nix CLI, configure nix itself, and the language basics.
To be honest, I can’t follow here. I recommend working through the following tutorials carefully, in sequence, to clear out your apparent misconceptions.
I know that most people come here because of the fabled NixOS, but in my opinion NixOS is a pretty advanced feature of the broader ecosystem because it requires substantial prerequisite knowledge to make good use of and actually - at least roughly, but correctly - understand how things fit together. You can’t sweep that under the rug and learning those things takes time.
Also, don’t get thrown off by the reproducibility discussion by @waffle8946. You’re here for the right reasons. But “reproducibility” is a technical term and means that you always get the same result for the same inputs. This is not exactly the case for Nix, for the stated reasons, but it’s good first approximation to assume that you’ll get pretty much always* the same system given the same Nix expression that fully describes a NixOS configuration.
@fricklerhandwerk, indeed, but I really am merely looking for a basic testbed to see how the configuration files work. I’m currently working on a long PowerShell script that configures multiple OSes, and wanted to see whether I could learn anything from how Nix(OS)'s are structured.
Your example of the system-provided one in /etc was perfect.
I’m confused because this should be almost or exactly the same as the one in the VM tutorial, except with lots of comments. If you used a graphical installer, there’s a sample at the end of the tutorial with a desktop environment enabled, maybe that’s closer to what you see on your machine.
Also I don’t believe “the file” will tell you much about how the system is put together, because that file is just a bunch of essentially random assignments, some more some less well-documented in the options search. And again, how you factor this expression is up to you, so there is not even a meaningful notion of “a file” — there may be as many as you want them to be for specifying one system, and they can live wherever you please.
The module system deep dive explains the underlying mechanics, and reading the source for each NixOS module you care about will inform you what concretely it does to the system.
Depends. nixos-generate-config only tries to generate filesystem layout (and possibly a few modules) based on the current system/chroot it is run from and the use case is primarily for interactive installation from a live OS.
If you want to create (not build) a config for another machine, nixos-generate-config is practically useless.
As a user, you can just create a configuration.nix for a specific machine anywhere, possibly including the filesystem layout of the target machine either directly or indirectly via imports[].
If this is the case then you probably want to decouple the config from the target machine(s) in your mind - like I said, think along the lines of “Dockerfile” - a recipe to build an image that is then deployed somewhere else.
For deploying multiple machines from a single “controller” (roughly like Ansible or Puppet for example) you may want to check out specialized tools like deploy-rs but that is a more advanced topic.
As for /etc/nixos/configuration.nix - that is the just default path nixos-rebuild looks for when (re)building a configuration locally.
Indeed, @jficz! I’m mostly creating a reference of how to achieve everything I want (it’s purely personal) before I start creating standardised configurations at work, to ensure that I know enough to choose a system that can achieve everything I want. It’s a roundabout method, but it’s taught me so much that I’m rather enjoying it now.
Additionally, since it works well for myself, it allows me a little more flexibility than the more organisation-focussed methods appear to.