This will go over the general organization of my nixos dotfiles because it took a lot of trial and error to get to where I am now, and hopefully it'll help you skip some of those trials and errors
What are they? dunno but it lets me use both nixpkgs stable and unstable. How do I do this?
What are they? dunno this either. Anyways, here's my current flake.nix and let's
go over it together. ...
denotes omitted code.
{
description = "System configuration";
inputs = {
stable.url = "github:nixos/nixpkgs/nixos-23.05";
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager/release-23.05";
home-manager.inputs.nixpkgs.follows = "stable";
...
};
outputs = { self, stable, unstable, home-manager, nix-matlab, ... }@inputs:
let
system = "x86_64-linux";
config = { allowUnfree = true; };
nixpkgs-overlays = ({ config, system, ...}: {
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [
# modifications to pkgs
(final: _prev: {
...
rebuild = final.callPackage ./programs/rebuild {};
...
unstable = import inputs.unstable {
system = final.system;
config.allowUnfree = true;
};
})
...
];
});
in {
# normal stuff
nixosConfigurations = {
zephyrus = stable.lib.nixosSystem {
inherit system;
specialArgs = inputs;
modules = [
nixpkgs-overlays
./hosts/zephyrus/configuration.nix
];
};
...
};
# home-manager stuff
defaultPackage.x86_64-linux = home-manager.defaultPackage.x86_64-linux;
homeConfigurations = {
bennett = home-manager.lib.homeManagerConfiguration {
pkgs = import stable { inherit system config; };
extraSpecialArgs = { inherit inputs; };
modules = [
nixpkgs-overlays
./users/bennett/home.nix
];
};
};
};
}
Let's start from the inputs. To actually have both stable and unstable, we need both of them as inputs in the first place. I also have home-manager following stable.
You can't directly use these inputs like stable.chromium
or something,
you have to import them first. What data type are they? dunno, I just
know you gotta import them with system
and config
first.
Next we got this nixpkgs-overlays
bit. This is actualy a module
I defined inline instead of a different file. It's the equivalent
of configuration.nix
or home.nix
. I'm putting it here because
I don't think there's enough stuff in it to really justify its own
file. I always put it in modules so I have easy acess to my unstable
packages.
If you take a look at the first unnamed overlay (there's others but
they're for app-specific overlays like matlab) you can see that there's
two important fields. I'll talk about rebuild
a little later when I
talk about my super duper convenient aliases, but unstable
is where
I actually turn it into a package.
How this overlay works is every property I add gets added to pkgs
when
I import them in other modules. So pkgs.rebuild
is my user defined package
and pkgs.unstable
is all the unstable packages. This means I can do stuff
like pkgs.unstable.osu-lazer
to get the most up-to-date version of osu so
it doesn't yell at me.
Finally we have the hosts/users. They're normal, just notice how I have
nixpkgs-overlays
first in the modules thing. idk if the order matters,
probably not, but it's gotta be there for sure if I wanna do my pkgs.unstable.*
syntax.
First we got this neat little rebuild thing. It's just a shell script that I made into a package that lets me rebuild my home manager config, my system config, both at the same time, and update my inputs.
rebuild/default.nix looks like this:
{ stdenv
, lib
, bash
, makeWrapper
}:
let
script = ./rebuild.sh;
name = "rebuild";
in
stdenv.mkDerivation {
inherit name;
phases = ["installPhase"];
buildInputs = [ bash ];
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin
cp ${script} $out/bin/${name}
wrapProgram $out/bin/${name} \
--prefix PATH : ${lib.makeBinPath [ bash ]}
'';
}
As you can see it's just a simple way to package a shell script. Is there a better way to do this? probably! Please let me know and I'll do that instead.
rebuild/rebuild.sh looks like this:
function config() { sudo nixos-rebuild switch --flake path:/etc/nixos#; }
function home() { nix run /etc/nixos switch -- --flake /etc/nixos; }
function update() { nix flake update path:/etc/nixos; }
if [ "$1" = "home" ]; then home; fi
if [ "$1" = "config" ]; then config; fi
if [ "$1" = "update" ]; then update; fi
if [ "$1" = "" ]; then config; home; fi
as you can see it simply builds it depending on what I tell it to do. It
assumes /etc/nixos becasue that's kinda the only way to make it easily portable.
I just chmod -R o+w /etc/nixos
whenever I'm on a new device so I don't need
to sudo everything all the time.
you can probably just check out everything else in the actual repo, most of
it is pretty self explanatory. I factor out common stuff into modules for
configuration.nix
and all my config stuff is shared between homes, also
as modules. I have a couple programs I've packaged myself and they sit in
programs
.
It's taken me like a whole year to get to this state where I'm actually happy with my config and it doesn't feel super slapdash so hopefully it'll be a little of use to you.