aboutsummaryrefslogtreecommitdiff
path: root/post/nixos-p1.typ
diff options
context:
space:
mode:
authorKumar Damani <me@kumardamani.net>2026-07-24 04:29:08 +0000
committerKumar Damani <me@kumardamani.net>2026-07-24 04:29:08 +0000
commit3d615f7b4c19abf34f23ff09ea587a597f2de42a (patch)
tree10a0e4c3e0fa2c9b0254bb1826ae89f67fbc7df0 /post/nixos-p1.typ
parent62fcd12a0a1ea557334dec1fa0cfdce69d003bd8 (diff)
converted to typst
Diffstat (limited to 'post/nixos-p1.typ')
-rw-r--r--post/nixos-p1.typ459
1 files changed, 459 insertions, 0 deletions
diff --git a/post/nixos-p1.typ b/post/nixos-p1.typ
new file mode 100644
index 0000000..2d248c8
--- /dev/null
+++ b/post/nixos-p1.typ
@@ -0,0 +1,459 @@
+#import "/global/common.typ": *
+
+#let doc = [
+Almost a guide to getting started with NixOS the modern (2023) way.
+
+There seems to be a shortage of written guides on the Internet for setting up
+NixOS the "modern" way - Flakes + Home Manager. It doesn't help that Nix's
+official docs are very disjointed so hopefully this will fill in some gaps that
+I observed when setting it all up.
+
+#fig("nixos-p1/fox.jpg", alt: "meme")
+
+#quote(block: true)[
+ Warning: NixOS is not exactly beginner friendly - you should have
+ familiarity installing Linux distros before trying this.
+]
+
+= But Why NixOS?
+
+Eh... FOMO regarding all the
+#extlink("https://www.google.com/search?q=nixos+memes&tbm=isch")[memes].
+
+There is one particular feature that is intriguing - the ability to roll-back
+your entire system (not incl. BIOS) in case of a misconfiguration or a broken
+update. *You can't do this with Ansible.* This allows you (in theory) to get
+the benefits of a rolling release as well as the stability benefits of a
+traditional distro.
+
+#quote(block: true)[
+ It takes the idea of reproducible builds, and extends it to the OS.
+]
+
+For example, NixOS will present you with all previous "builds" at boot time for
+you to revert to in case something gets messed up.
+
+#fig("nixos-p1/boot.png", alt: "boot prompt")
+
+= Things I want to explore as part of this exercise:
+
++ How hard is it to go from a minimal install to productive? At minimum I need
+ a graphical environment with working vol, mic, camera, wifi, and hibernation.
+ Is it harder than doing the same in something like Manjaro?
++ Is Wayland truly ready?
++ Try out #extlink("https://github.com/djpohly/dwl")[`dwl`] (the Wayland port
+ of `dwm` by the #extlink("https://suckless.org")[suckless] folks)
+
+= Constraints
+
++ I want to stick to the "Nix" way of doing things as much as possible _where
+ it makes sense to me_.
++ Stick to Wayland only applications as much as possible.
+
+= Spoilers! (End result)
+
+#fig("nixos-p1/rice.png", alt: "my rice")
+
+(Probably too ugly for r/unixporn, but works for me :)
+
+= Installation
+
+== Getting a Live USB going
+
+- I used the #extlink("https://nixos.org/download.html#nixos-iso")[minimal iso].
+- Create a bootable USB with the usual - `sudo dd if=/path/to/iso of=/dev/sdX bs=4M`.
+- Boot up.
+- Then start following the steps for
+ #extlink("https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual")[manual
+ installation] from the official guide to complete the install.
+
+#quote(block: true)[
+ Make sure to give SWAP as much space as your memory capacity for
+ hibernation to work properly.
+]
+
+#quote(block: true)[
+ Wifi did not work for me out of the box. So I used my phone to tether via
+ USB.
+]
+
+= First boot
+
+If everything went well, you should be presented with a TTY prompting you to
+login:
+
+```
+NixOS ...
+Login: <your username>
+Password: <your password>
+```
+
+Once you login, you will still just have a TTY, but we can now go ahead and
+start installing our graphical environment.
+
+= Housekeeping
+
+- You should have two NixOS config files in `/etc/nixos/`:
+
+```
+configuration.nix
+hardware-configuration.nix
+```
+
+- Edit the `configuration.nix` file by setting the correct values for hostname,
+ networking, timezone and users. I also add a few basic system-wide packages
+ here such as `git, rsync, neovim, htop` etc.
+
+- To _apply and use_ your changes to any of these files you need to run:
+
+```bash
+sudo nixos-rebuild switch
+```
+
+- Since we want all our configuration to be version controlled, I copied these
+ files to live under my user's config: `~/.config/{nix, nixpkgs}/`:
+
+```bash
+cp /etc/nix/nix.conf ~/.config/nix/nix.conf
+cp /etc/nixos/configuration.nix ~/.config/nixpkgs/configuration.nix
+```
+
+Nix will now use these user-specific files to read its config :)
+
+== Flakes Support
+
+Nix (the pkg mgr) does not come with Flakes support out-of-the-box. So we need
+to enable it:
+
++ In `~/.config/nix/nix.conf` add:
+
+```
+experimental-features = nix-command flakes
+```
+
++ Apply it:
+
+```bash
+sudo nixos-rebuild switch
+```
+
+Read about #extlink("https://nixos.wiki/wiki/Flakes")[Flakes].
+
+== Home Manager Support
+
+Now we can install the Home-Manager flake.
+
++ Init our base flake:
+
+```bash
+cd ~/.config/nixpkgs
+nix flake init
+```
+
+This should generate two files:
+
+```
+flake.nix
+flake.lock
+```
+
++ Next we tell `flake.nix` to manage all our configuration (system + home) for
+ our system:
+
+```nix
+{
+ description = "NixOS configuration";
+
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+ home-manager.url = "github:nix-community/home-manager";
+ home-manager.inputs.nixpkgs.follows = "nixpkgs";
+ nixos-hardware.url = "github:NixOS/nixos-hardware/master";
+ };
+
+ outputs = inputs@{ nixpkgs, home-manager, nixos-hardware, ... }: {
+ nixosConfigurations = {
+ # Change below to use your hostname from configuration.nix
+ "art-sr" = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [
+ ./configuration.nix
+ nixos-hardware.nixosModules.framework
+ home-manager.nixosModules.home-manager
+ {
+ home-manager.useGlobalPkgs = true;
+ home-manager.useUserPackages = true;
+ # Change below to use your username from configuration.nix
+ home-manager.users.kdam0 = import ./home.nix;
+
+ # Optionally, use home-manager.extraSpecialArgs to pass
+ # arguments to home.nix
+ }
+ ];
+ };
+ };
+ };
+}
+```
+
+#quote(block: true)["art-sr" is my hostname for this machine.]
+
+In my case, I also have the following two lines specifically to load settings
+for my hardware:
+
+```
+ nixos-hardware.url = "github:NixOS/nixos-hardware/master";
+ ...
+ nixos-hardware.nixosModules.framework
+```
+
+you will need to modify these values based on your
+#extlink("https://github.com/NixOS/nixos-hardware")[hardware support].
+
++ Create a `~/.config/nixpkgs/home.nix` file with your values:
+
+```nix
+{ config, pkgs, ...}:
+{
+ home.username = "kdam0";
+ home.homeDirectory = "/home/kdam0";
+
+ programs.home-manager.enable = true;
+ home.stateVersion = "22.11";
+
+ services.gpg-agent = {
+ enable = true;
+ defaultCacheTtl = 1800;
+ enableSshSupport = true;
+ };
+}
+```
+
++ Apply:
+
+```bash
+sudo nixos-rebuild switch
+```
+
+#quote(block: true)[
+ It took a few attempts to get NixOS to re-build successfully. I ran into a
+ few different issues involving users, and hostnames while following the
+ official docs until I arrived at the configs above which worked.
+]
+
+Read about
+#extlink("https://nix-community.github.io/home-manager/index.html#ch-nix-flakes")[Home
+ Manager flake].
+
+*This would be a good time init a git repo in `~/.config/nixpkgs/` and publish
+your progress.*
+
+= Setting up the GUI
+
+== Window Manager + bar + system info.
+
+Getting `dwl` is easy enough. In my `home.nix`:
+
+```
+ home.packages = [
+ pkgs.dwl
+ ...
+ ];
+```
+
+This will install `dwl` on a rebuild. Then I can run it with `dwl`.
+
+Oh it fails...something about permissions... In
+`~/.config/nixpkgs/configuration.nix` make sure you have:
+
+```
+ security.polkit.enable = true;
+```
+
+Oh it fails again with GLE errors :( Add:
+
+```
+ hardware.opengl = {
+ enable = true;
+ driSupport = true;
+ };
+```
+
+*Sweet now it launches!*
+
+But of course I need to configure the keys - that's the whole point of a WM.
+Additionally, `dwl` requires a re-build on every config change...
+
+*How do I tell Nix to use my config file while installing/building `dwl`?*
+
+Lucking all packages (`pkgs.*`) build files are defined on their GitHub. We can
+see that we are allowed to pass in a `conf` argument to
+#extlink("https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/window-managers/dwl/default.nix")[this]
+file.
+
+After a bit of digging around, I arrived at how to do it:
+
++ First copy your `config.h` to `~/.config/nixpkgs/dwl/config.h`.
++ Then point to it in your `home.nix`:
+
+```
+ home.packages = [
+ (pkgs.dwl.override {
+ # trying to supply config.home.homeDirectory here leads to "impure" usage.
+ # so disabling it for now.
+ # conf = (builtins.readFile "${config.home.homeDirectory}/.config/dwl/config.h");
+ conf = ./dwl/config.h;
+ })
+ ...
+ ];
+```
+
+#quote(block: true)[
+ I know I can just clone the source myself and build it, but I like to use
+ the default package manager whenever possible to manage packages.
+]
+
+Of course since `dwl` is as minimal as it gets, it does not ship with a bar. We
+have many options for which bar to use, I have very little use for a bar, so I
+kept it very simple and went with `somebar`:
+
+```
+ home.packages = [
+ ...
+ pkgs.somebar
+ ...
+ ];
+```
+
+If you want status info on your bar you can use something like `someblocks` -
+which will let you script simple scripts with text output you want displayed in
+each block. This will need to be cloned and built manually as it is not
+available in the Nix repos.
+
+Oh but you probably don't have `make` or any requirements to actually build
+it...fear not:
+
+```bash
+nix-shell -p gnumake
+```
+
+which put you in a temporary environment with all the common build tools
+available. Now you can:
+
+```bash
+sudo make install
+```
+
+`wbg` is a simple background setter for Wayland......aaaand BAM!
+
+#fig("nixos-p1/dwl.png", alt: "dwl pic")
+
+== Terminal
+
+I use #extlink("https://codeberg.org/dnkl/foot")[`foot`].
+
+Create the config file in `~/.config/nixpkgs/foot/foot.ini`:
+
+```
+# for transparency #
+[colors]
+alpha=0.7
+```
+
+Use it in `home.nix`:
+
+```
+ home.file.".config/foot/foot.ini".source = ../../common/foot/foot.ini;
+```
+
+#quote(block: true)[I use this pattern for pretty much all my _dotfiles_:]
+
+```
+ # script that sets a bg.
+ home.file."bg.sh".source = common/bg.sh;
+ # script that starts my gui env.
+ home.file."start.sh".source = common/start.sh;
+ # foot config
+ home.file.".config/foot/foot.ini".source = common/foot/foot.ini;
+ # wofi config (app launcher)
+ home.file.".config/wofi/style.css".source = common/wofi/style.css;
+ # mako config (notifications)
+ home.file.".config/mako/config".source = common/mako/config;
+```
+
+== Sound
+
+In my `configuration.nix`:
+
+```
+ security.rtkit.enable = true;
+ services.pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ wireplumber.enable = true;
+ media-session.enable = false;
+ jack.enable = true;
+ systemWide = false;
+ };
+```
+
+== Nextcloud
+
+I want a purely CLI way to handle this, and a periodic sync is sufficient for
+me. We do this with `systemd-timers` (Nix advises against `cron`). In my
+`home.nix`:
+
+```
+ systemd.user.services = {
+ nextcloud-sync = {
+ Unit = {
+ Description = "Auto sync Nextcloud";
+ After = "network-online.target";
+ };
+ Service = {
+ Type = "simple";
+ EnvironmentFile = "${config.home.homeDirectory}/.nextcloud.env";
+ ExecStart = ''
+ ${pkgs.nextcloud-client}/bin/nextcloudcmd \
+ -h --non-interactive \
+ --user "''${NEXTCLOUD_USER}" \
+ --password "''${NEXTCLOUD_PASSWORD}" \
+ ''${NEXTCLOUD_DIR} \
+ ''${NEXTCLOUD_URL}
+ '';
+ TimeoutStopSec = "180";
+ KillMode = "process";
+ KillSignal = "SIGINT";
+ };
+ Install.WantedBy = ["multi-user.target"];
+ };
+ };
+ systemd.user.timers = {
+ nextcloud-sync = {
+ Unit.Description = "Automatic sync files with Nextcloud when booted up after 5 minutes then rerun every 10 minutes";
+ Timer.OnUnitActiveSec = "10min";
+ Install.WantedBy = ["multi-user.target" "timers.target"];
+ };
+ };
+ systemd.user.startServices = true;
+```
+
+= Conclusions
+
++ Yes setting things up from a minimal iso is harder than in Manjaro. Although
+ I got everything I wanted working, there were many times I felt like giving
+ up. (Aside: I am _so grateful_ for Manjaro, and Arch wikis). That said, I
+ expect this friction is a one-time cost for building familiarity with Nix,
+ and well worth the benefits that come with it.
++ You bet Wayland is ready. Multi-monitor works out-of-the-box, all my apps
+ support it, and things just _feel_ more polished than I have ever felt with
+ Xorg.
++ `dwl` is as awesome as I had hoped! This is my daily driver now.
+
+= My configs
+
+All the configs discussed (and more) are in my
+#extlink("https://gitlab.com/kdam0/dotfiles-nix")[nixdotfiles repo].
+]