Always nice to see people documenting flake-less, channel-less approaches.
Now that nixos-rebuild has gained the ability to pass it an instantiated NixOS system, I’m quite fond of that approach:
# name this e.g. mymachine.nix
let
nixpkgs = builtins.fetchGit {
name = "nixos-24.05-2024-05-31";
url = "https://github.com/NixOS/nixpkgs";
ref = "refs/heads/nixos-24.05";
rev = "805a384895c696f802a9bf5bf4720f37385df547";
};
in
import "${nixpkgs}/nixos/lib/eval-config.nix" {
system = null;
modules = [
./configuration.nix
];
}
and then using nixos-rebuild -f mymachine.nix
.
Also just wanted to mention that, there’s also some follow-ups to make this even more powerful (one by @justinas themselves)
That’s neat, thank you for pointing it out! I personally use colmena for all my machines instead of nixos-rebuild, but I might want to revisit that with these improvements
That’s great!
I have been doing before
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/5ef6c425980847c78a80d759abc476e941a9bf42.tar.gz";
pkgs = import nixpkgs {};
what-is-my-ip = import ./what-is-my-ip.nix {inherit pkgs;};
nixos = import "${nixpkgs}/nixos" {
configuration = {
users.users.alice = {
isNormalUser = true;
# enable sudo
extraGroups = ["wheel"];
packages = [
what-is-my-ip
];
initialPassword = "swordfish";
};
system.stateVersion = "24.05";
};
};
in
nixos.vm
How is this different? Could I have returned back nixos.config.build.toplevel
(or whatever it is) and done so already?
I love the simplicity of 1-file examples.
The key difference is that the nixpkgs
you import here is only used for building your configuration and then available nowhere else. Notably, if within that system you then do nix-shell
, which Nixpkgs will it use?
One nixpkgs to rule them all! Personally if i had the setup I want I’d use my npins sources to set my nixpkgs source, but I would like to be able to use a local nixpkgs without copying it into store every eval.
Some day when i finally unflake!
Yeah, at the end of the day what nixos-rebuild does is invoke nix-build
for either toplevel
or vm
, depending on whether you’re doing build
(switch
etc.) or build-vm
.
.
From this information, one could pretty much write a NixOS build tool: it really is just
nix build -f '<nixpkgs/nixos>' config.system.build.toplevel
(in old syntax,nix-build '<nixpkgs/nixos>' -A config.system.build.toplevel
), thenresult/bin/switch-to-configuration
. That’s all it does.
This bit me before Unfortunately,
nixos-rebuild
is also responsible for generating the system
and system-$n-link
symlinks in /nix/var/nix/profiles/system
Yep @SergeK that’s why there are so many and why there’s no point writing them in Rust or any fancy language. Here’s a link to my “nixos-rebuild” reimplemented in fish-shell. Since i don’t support remote building or any other fancy flags it’s really barebones and should make for a good example to build your own with.
The only “magic” is that i pipe the output of nix build through tee to save it to file and process it with “nom” that makes for a nicer rebuild TUI progress experience.
Looks like I had already
# Put nixpkgs into /etc/nixpkgs for convenience
environment.etc.nixpkgs.source = inputs.nixpkgs;
# Point nixpath to that nixpkgs so that the system uses the same nix
nix = {
nixPath = ["nixpkgs=/etc/nixpkgs" "nixos-config=/etc/nixos/configuration.nix"];
Not sure if i’m missing more.
This makes me so glad I wrote this post!
Because it took me quite a few iterations to find this solution from first principles, and how I’m hearing from a handful of people that they’ve been doing it like this all along. It really seems to be a useful pattern, and we should document and spread it more. Maybe somewhere in the Wiki as well?
Also no you’re not really missing out on much, the base solution really is only a couple of lines long.
Cool.
I can’t remember whose nixOS config I cribbed it from; maybe @Infinisil or jonringer.
Either way – I can attest 100% it’s a good base setting for a starter NixOS project.
(Anything else is “weird” – cause I couldn’t figure out what the nixpath was actually set to.)