aboutsummaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorKumar Damani <me@kumardamani.net>2023-04-09 21:01:11 +0000
committerKumar Damani <me@kumardamani.net>2023-04-09 21:01:46 +0000
commitcf259bfe2fdc33894f10083737776f79903a6fbe (patch)
treebf1ca4e246ec35d9df9f96f6612294b2aa08a773 /content
parent885fea1bd35d17ef4c4d5d75ffc6ac5c4df09e30 (diff)
nixos post
Diffstat (limited to 'content')
-rw-r--r--content/post/nixos-p1/boot.pngbin0 -> 12893 bytes
-rw-r--r--content/post/nixos-p1/dwl.pngbin0 -> 3082421 bytes
-rw-r--r--content/post/nixos-p1/fox.jpgbin0 -> 30886 bytes
-rw-r--r--content/post/nixos-p1/index.md385
-rw-r--r--content/post/nixos-p1/rice.pngbin0 -> 1670023 bytes
5 files changed, 385 insertions, 0 deletions
diff --git a/content/post/nixos-p1/boot.png b/content/post/nixos-p1/boot.png
new file mode 100644
index 0000000..4e3d972
--- /dev/null
+++ b/content/post/nixos-p1/boot.png
Binary files differ
diff --git a/content/post/nixos-p1/dwl.png b/content/post/nixos-p1/dwl.png
new file mode 100644
index 0000000..8ecbe4d
--- /dev/null
+++ b/content/post/nixos-p1/dwl.png
Binary files differ
diff --git a/content/post/nixos-p1/fox.jpg b/content/post/nixos-p1/fox.jpg
new file mode 100644
index 0000000..3ace57f
--- /dev/null
+++ b/content/post/nixos-p1/fox.jpg
Binary files differ
diff --git a/content/post/nixos-p1/index.md b/content/post/nixos-p1/index.md
new file mode 100644
index 0000000..920ca94
--- /dev/null
+++ b/content/post/nixos-p1/index.md
@@ -0,0 +1,385 @@
++++
+author = "Kumar Damani"
+title = "Adventures in NixOS - Part 1"
+date = "2023-03-24"
+draft = false
+description = "Guide to getting started with NixOS the modern way."
+tags = [
+ "technology"
+]
++++
+
+Almost a guide to getting started with NixOS the modern (2023) way.
+<!--more-->
+
+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.
+
+![meme](fox.jpg)
+
+> 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 [memes](https://www.google.com/search?q=nixos+memes&tbm=isch).
+
+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.
+
+> 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.
+![boot prompt](boot.png)
+
+## Things I want to explore as part of this exercise:
+1. 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?
+2. Is Wayland truly ready?
+3. Try out [`dwl`](https://github.com/djpohly/dwl) (the Wayland port of `dwm` by the [suckless](https://suckless.org) folks)
+
+## Constraints
+1. I want to stick to the "Nix" way of doing things as much as possible
+*where it makes sense to me*.
+2. Stick to Wayland only applications as much as possible.
+
+## Spoilers! (End result)
+![my rice](rice.png)
+(Probably too ugly for r/unixporn, but works for me :)
+
+## Installation
+### Getting a Live USB going
+* I used the [minimal iso](https://nixos.org/download.html#nixos-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 [manual installation](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual)
+from the official guide to complete the install.
+
+> Make sure to give SWAP as much space as your memory capacity for hibernation to work properly.
+
+> 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:
+1. In `~/.config/nix/nix.conf` add:
+```
+experimental-features = nix-command flakes
+```
+
+2. Apply it:
+```bash
+sudo nixos-rebuild switch
+```
+Read about [Flakes](https://nixos.wiki/wiki/Flakes).
+
+### Home Manager Support
+Now we can install the Home-Manager flake.
+1. Init our base flake:
+```bash
+cd ~/.config/nixpkgs
+nix flake init
+```
+This should generate two files:
+```
+flake.nix
+flake.lock
+```
+2. 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
+ }
+ ];
+ };
+ };
+ };
+}
+```
+>"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 [hardware support](https://github.com/NixOS/nixos-hardware).
+
+3. 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;
+ };
+}
+```
+
+4. Apply:
+```bash
+sudo nixos-rebuild switch
+```
+> 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 [Home Manager flake](https://nix-community.github.io/home-manager/index.html#ch-nix-flakes).
+
+**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
+[this](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/window-managers/dwl/default.nix)
+file.
+
+After a bit of digging around, I arrived at how to do it:
+
+1. First copy your `config.h` to `~/.config/nixpkgs/dwl/config.h`.
+2. 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;
+ })
+ ...
+ ];
+```
+
+> 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!
+
+![dwl pic](dwl.png)
+
+### Terminal
+I use [`foot`](https://codeberg.org/dnkl/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;
+```
+
+> 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
+1. 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.
+2. 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.
+3. `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 [nixdotfiles repo](https://gitlab.com/kdam0/dotfiles-nix).
diff --git a/content/post/nixos-p1/rice.png b/content/post/nixos-p1/rice.png
new file mode 100644
index 0000000..4fd97cf
--- /dev/null
+++ b/content/post/nixos-p1/rice.png
Binary files differ