= foo-dogsquared's NixOS config
:toc:

This is my NixOS config as a link:https://www.tweag.io/blog/2020-05-25-flakes/[Nix flake].

I finally have some time trying to grok flakes and redo my NixOS config from scratch after leaving it for some time (because I have work and have to quickly set things up without me trying to debug how NixOS works).
Here is the result.




== Installation

Since this uses Nix flakes, you should have Nix v2.4 and above installed.

This primarily uses Nix flakes so you can have a preview of what's available in my config.

[source, shell]
----
nix flake show github:foo-dogsquared/nixos-config
----

It should export my NixOS configurations of my different hosts (of only one so far excluding VMs and VPSs ;p) among other things.
To install it, run the `nixos-install --flake github:foo-dogsquared/nixos-config#ni`.
(Please see the respective appropriate host README for more information.)

TIP: If you found some error regarding something in restricted mode, you can run the installation with `--impure` flag (i.e., `nixos-install --impure --flake github:foo-dogsquared/nixos-config#ni`).




== What's in my flake?

You can see the full details with `nix flake show`.
As a helpful summary, here's what my flake should contain sorting from the most interesting and helpful outputs to the most boring and unnecessary.

* `packages` contains link:./pkgs[my custom packages].
It supports the default list of systems as defined from link:https://github.com/numtide/flake-utils[`flake-utils`].

* `devShells` from link:./shells/[my custom environments].
Similar to `homeManagerConfigurations`, you can easily use it outside of NixOS.

* `homeManagerConfigurations` contains my various link:https://github.com/nix-community/home-manager[home-manager] configurations from link:./users/home-manager/[`./users/home-manager/`].
The neat thing about it is you can easily install it in a non-NixOS Linux distro.

* `nixosConfigurations` which is where you can install my various NixOS configurations directly (e.g., `nixos-install --flake MY_FLAKE_URL#HOST`).
This mainly uses the link:./hosts/[hosts configuration].

* `homeManagerModules` are where my link:./modules/home-manager[custom home-manager modules] to be exported.
footnote:[This is more useful than my NixOS modules.]

* `nixosModules` are composed from NixOS modules defined in link:./modules/nixos[`./modules/nixos`].
It can be used as additional modules for your own NixOS config in case you want to use mine for whatever reason.
footnote:[I don't know why did I put it there but eh...]


* `templates` which contains my templates.
Though, these are just templates mostly for my own purposes so it is not as useful as the other outputs.

* `defaultTemplate` which is my go-to template.
Ehhh, same comment as `templates`.

* `devShell` is the development shell for this project.
It's just there for convenience purposes.

* `lib` is defined from link:./lib/[my custom library].
It's another unnecessary export but it's there.




== Project structure

My NixOS config should look like the following:

[source, tree]
----
nixos-config
├── hosts/
├── lib/
├── modules/
├── pkgs/
├── secrets/
├── shells/
├── templates/
├── users/
├── flake.lock
├── flake.nix
└── README.adoc
----

* link:./hosts/[`./hosts/`] contain machine-specific configuration.
This usually configures like the hardware setup, timezone, and users.
Host configurations are also exported in the flakes in `outputs.nixosConfigurations`.

* link:./modules/[`./modules/`] contain my custom modules including NixOS and home-manager modules.
For more information, see the link:./modules/README.adoc[related documentation].

* link:./pkgs/[`./pkgs/`] contains my custom packages.
It is exported in the flakes at `outputs.packages` compiled through various systems.

* link:./secrets/[`./secrets/`] contains my secrets managed with link:https://github.com/ryantm/agenix[agenix].
footnote:[It is advised you should minimize SSH keys with passphrases since it is annoying to reenter passwords every time.]

* link:./shells/[`./shells/`] contains my development shells for interacting with the usual type of projects.
Setting this up can bring benefits outside of NixOS (unless you're interacting with projects with any OpenGL-related stuff).
footnote:[Since packages brought from Nix shells can only work with the store, a container might be better at some situations.]

* link:./templates/[`./templates/`] contains my custom templates handy for quickly initializing for various types of projects.

* link:./users/[`./users/`] contains my link:https://github.com/nix-community/home-manager[home-manager] configurations.
It is exported in the flakes at `outputs.homeConfigurations`.
For more information, see the link:./users/README.adoc[related documentation].




== TODO

In order of priority:

* [x] Create custom modules.
* [x] Create a themes system similar to link:https://github.com/hlissner/dotfiles[this NixOS config].
* [ ] Create a good workflow for creating ISOs.
* [x] Create development shells.
* [x] Manage secrets with agenix.
* [ ] Create a good workflow for tests.
* [x] Automate backups with NixOS config.
* [x] Create custom packages and export it to flakes. (Maybe consider making it to upstream)
* [x] Create cluser-wide configs.
* [x] Create host-wide configs.
* [x] Create user-specific configs with home-manager.
* [x] ~Steal~ Get some ideas from link:https://github.com/divnix/devos[this overengineered template].
* [x] Make use of other established utilities such as link:https://github.com/divnix/digga/[digga], link:https://github.com/gytis-ivaskevicius/flake-utils-plus[flake-utils-plus], and link:https://github.com/nix-community/home-manager[home-manager] once I'm familiar to create my own Nix programs.

Out of scope:

* Text editor configurations.
They are often updated. I don't want to rebuild it every time I change it.

* Migration of my link:https://github.com/foo-dogsquared/dotfiles[dotfiles].
I still use it on other non-NixOS systems.




== Frequently asked questions (FAQ)

More like "Most anticipated questions (MAQ)" since almost no one asked me about this yet. :)
However, it doesn't roll off the tongue.

[qanda]
Hello! I'm new to Nix and NixOS, where should I start?::
Oh no, you've seen the multiple configurations from other systems, didn't you?
I hope you're ready for some time understanding because the learning curve is steeper than the link:https://en.wikipedia.org/wiki/Troll_Wall[Troll Wall].
I've written link:https://foo-dogsquared.github.io/blog/posts/moving-into-nixos/[a blog post regarding my experience with Nix] with a bunch of links for getting started.
Fortunately footnote:[Or unfortunately from a different perspective.], it is mostly the same experience now that I've revisited it.
(That said, Nix Pills is getting better!)
+
For a more practical start, I recommend to look into several configurations to see the general gist of configuration with Nix.
Here's a few I personally dug into:
+
* https://github.com/divnix/devos
* https://github.com/hlissner/dotfiles
* https://github.com/thiagokokada/nix-configs

Any requirements for this setup?::
You only need Nix 2.4 installed with the experimental features for Nix command and flakes enabled (i.e., `experimental-features = nix-command flakes`).

Hey! I have an error something like `/nix/${HASH}-nmd/` from my installation. Why it doesn't work?::
This error seems to be related to home-manager.
See this link:https://github.com/nix-community/home-manager/issues/2074[issue] for more details.
Basically, you have to add `--impure` flag when running `nixos-install`.

What is my experience on Nix flakes?::
link:https://youtu.be/iWJKZK_1l88[I LIKE IT!]
There are still some hiccups like the strict tie-in to Git which leads to strange experience like having to add untracked files just to be recognized.
However, this feature is still in the works so no surprise there.
+
With that said, it is workable to be a daily part of the NixOS experience especially with the benefits of Nix flakes.
+
* More user-friendly compared to Nix channels.
* Just one reference file to know what is being exported from a project.
* Unification with commonly-agreed schemas.
+
This feature somewhat helped me understand more about the Nix language, oddly.
I guess those lightbulb moments can come from random places.

Is this based from link:https://github.com/divnix/devos[devos]?::
Yes but I've created this from scratch.
One of my goals when creating this config is to use as little dependency as much as possible and to understand more what's going under the hood with Nix.
At the time I've rewritten this configuration, I have little idea about Nix as a language and I find devos to be overwhelming so I doubled down to create from scratch.
+
However, I can say that my configuration is moving in a similar direction to devos (which is intended to be modified anyways) as I explore more of Nix.
In fact, I've based much of my config from it and may even be ended up as one.
It is nice that such a project exists serving as a reference for bigger configurations.




== Inspirations

I ~stole~ got several parts of this configuration from the following projects:

* link:https://github.com/divnix/devos[devos, an overengineered configuration framework.]
I'm slowly grokking Nix and its ecosystem so I didn't use this outright.
Though, this is where my config is heading to be and instead slowly making parts of my config based from this template.

* link:https://github.com/divnix/digga/[digga, an flake utility library for your overengineered config.]
I also stole parts of it for my custom library.
I may have to use this at some point.

* link:https://github.com/hlissner/dotfiles/[hlissner's dotfiles, the original inspiration for this functional abomination of a configuration.]
Very nice.
