home | section main page


NixOS Configuration

Table of Contents

1. Introduction

This is my NixOS configuration. It is a part of my monorepo, and this file automatically tangles to all the under the nix/ directory in my monorepo git repository. My monorepo also stores my website, as my website stores my elfeed and emacs configurations. Additionally, I want to track my emacs configuration with my Nix configuration. Having them in one repository means that my emacs configuration is pinned to my flake.

Hence, my monorepo serves a dual purpose, as do many of the files within my monorepo. They are often data files used in my configuration (i.e. emacs, elfeed, org-roam, agenda, journal, etc…) and they are webpages as well. This page is one such example of this concept.

2. Flake.nix

The flake is the entry point of the NixOS configuration. Here, I have a list of all the systems that I use with all the modules that they use. My NixOS configuration is heavily modularized, so that adding new configurations that add modifications is made simple.

{
  description = "Emacs centric configurations for a complete networked system";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nur.url = "github:nix-community/NUR";
    sops-nix.url = "github:Mic92/sops-nix";
    scripts.url = "github:ret2pop/scripts";
    wallpapers.url = "github:ret2pop/wallpapers";
    sounds.url = "github:ret2pop/sounds";
    nix-topology = {
      url = "github:oddlama/nix-topology";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    deep-research = {
      url = "github:ret2pop/ollama-deep-researcher";
    };
    home-manager = {
      url = "github:nix-community/home-manager/release-25.05";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    lanzaboote = {
      url = "github:nix-community/lanzaboote/v0.4.1";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nixos-dns = {
      url = "github:Janik-Haag/nixos-dns";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, home-manager, nur, disko, lanzaboote, sops-nix, nix-topology, nixos-dns, deep-research, ... }@attrs:
    let
      hostnames = [
        "affinity"
        "continuity"
        "installer"
        "spontaneity"
        # add hostnames here
      ];

      system = "x86_64-linux";

      pkgs = import nixpkgs { inherit system; };

      generate = nixos-dns.utils.generate nixpkgs.legacyPackages."${system}";

      dnsConfig = {
        inherit (self) nixosConfigurations;
        extraConfig = import ./dns/default.nix;
      };

      # function that generates all systems from hostnames
      mkConfigs = map (hostname: {name = "${hostname}";
        value = nixpkgs.lib.nixosSystem {
          inherit system;
          specialArgs = attrs;
          modules = if (hostname == "installer") then [
            (./. + "/systems/${hostname}/default.nix")
            { networking.hostName = "${hostname}"; }
            nix-topology.nixosModules.default
          ] else [
            {
              environment.systemPackages = with nixpkgs.lib; [
                deep-research.packages."${system}".deep-research
              ];
            }
            nix-topology.nixosModules.default
            lanzaboote.nixosModules.lanzaboote
            disko.nixosModules.disko
            home-manager.nixosModules.home-manager
            sops-nix.nixosModules.sops
            nixos-dns.nixosModules.dns
            {
              nixpkgs.overlays = [ nur.overlays.default ];
              home-manager.extraSpecialArgs = attrs // { systemHostName = "${hostname}"; };
              networking.hostName = "${hostname}";
            }
            (./. + "/systems/${hostname}/default.nix")
          ];
        };
      });

      mkDiskoFiles = map (hostname: {
        name = "${hostname}";
        value = self.nixosConfigurations."${hostname}".config.monorepo.vars.diskoSpec;
      });

    in {
      nixosConfigurations = builtins.listToAttrs (mkConfigs hostnames);

      evalDisko = builtins.listToAttrs (mkDiskoFiles (builtins.filter (x: x != "installer") hostnames));

      topology."${system}" = import nix-topology {
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ nix-topology.overlays.default ];
        };
        modules = [
          ./topology/default.nix
          { nixosConfigurations = self.nixosConfigurations; }
        ];
      };

      devShell."${system}" = with pkgs; mkShell {
        buildInputs = [
          fira-code
          python3
          poetry
          statix
          deadnix
        ];
      };

      packages."${system}" = {
        zoneFiles = generate.zoneFiles dnsConfig;
        octodns = generate.octodnsConfig {
          inherit dnsConfig;

          config = {
            providers = {
              cloudflare = {
                class = "octodns_cloudflare.CloudflareProvider";
                token = "env/CLOUDFLARE_TOKEN";
              };
              config = {
                check_origin = false;
              };
            };
          };
          zones = {
            "ret2pop.net." = nixos-dns.utils.octodns.generateZoneAttrs [ "cloudflare" ];
            "nullring.xyz." = nixos-dns.utils.octodns.generateZoneAttrs [ "cloudflare" ];
          };
        };
      };
    };
}

Note that the configurations are automatically generated with he mkConfigs function.

3. Sops Configuration

In order to use the sops configuration, you must change the age public key to the one that you own:

keys:
  - &primary age165ul43e8rc0qwzz2f2q9cw02psm2mkudsrwavq2e0pxs280p64yqy2z0dr
creation_rules:
  - path_regex: secrets/secrets.yaml$
    key_groups:
      - age:
        - *primary

also note that you will have to write your own secrets.yaml file, with an entry called mail, which is used for the imaps and smtps password.

4. Nix DNS

{
  defaultTTL = 120;
}

5. Nix Topology

Nix Topology generates a nice graph of all my hosts. You can view this graph by running nix build .#topology.x86_64-linux.config.output.

{ config, ... }:
let
  inherit
    (config.lib.topology);
in
{
  nodes = {
    spontaneity = {
      interfaces.wan.network = "remote";
    };
    installer = {
      interfaces.lan.network = "home";
    };
    affinity = {
      interfaces.lan = {
        network = "home";
        physicalConnections = [
          {
            node = "spontaneity";
            interface = "wan";
          }
          {
            node = "installer";
            interface = "lan";
          }
        ];
      };
    };
    continuity = {
      interfaces.lan = {
        network = "home";
        physicalConnections = [
          {
            node = "spontaneity";
            interface = "wan";
          }
          {
            node = "affinity";
            interface = "lan";
          }
        ];
      };
    };
  };
  networks = {
    home = {
      name = "Home Network";
      cidrv4 = "192.168.1.1/24";
    };
    remote = {
      name = "Remote Network";
      cidrv4 = "144.202.27.169/32";
    };
  };
}

6. Modules

6.1. Vars

Variables used for regular configuration in your system default.nix file. The options are largely self-documenting.

{ lib, ... }:
{
  options.monorepo.vars = {
    device = lib.mkOption {
      type = lib.types.str;
      default = "/dev/sda";
      example = "/dev/nvme0n1";
      description = "device that NixOS is installed to";
    };

    fileSystem = lib.mkOption {
      type = lib.types.str;
      default = "ext4";
      example = "btrfs";
      description = "filesystem to install with disko";
    };

    diskoSpec = lib.mkOption {
      type = lib.types.attrs;
      description = "retains a copy of the disko spec for reflection";
    };

    userName = lib.mkOption {
      type = lib.types.str;
      default = "preston";
      example = "myUser";
      description = "system username";
    };

    fullName = lib.mkOption {
      type = lib.types.str;
      default = "Preston Pan";
      example = "John Doe";
      description = "Full Name";
    };

    gpgKey = lib.mkOption {
      type = lib.types.str;
      default = "AEC273BF75B6F54D81343A1AC1FE6CED393AE6C1";
      example = "1234567890ABCDEF...";
      description = "GPG key fingerprint";
    };

    remoteHost = lib.mkOption {
      type = lib.types.str;
      default = "ret2pop.net";
      example = "example.com";
      description = "Address to push to and pull from for website and git repos";
    };

    timeZone = lib.mkOption {
      type = lib.types.str;
      default = "America/Vancouver";
      example = "America/Chicago";
      description = "Linux timezone";
    };

    monitors = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      default = [
        "HDMI-A-1"
        "eDP-1"
        "DP-2"
        "DP-3"
        "DP-4"
        "LVDS-1"
      ];
      example = [];
      description = "Monitors that waybar will use";
    };
  };
}

6.2. Default Profile

Again, these are self documenting variables that you may see used below. These are to be used under default.nix in the systems folder.

{ lib, config, pkgs, ... }:
{
  imports = [
    ./configuration.nix
    ./vars.nix
  ];

  options = {
    monorepo = {
      profiles = {
        cuda.enable = lib.mkEnableOption "Enables CUDA support";
        documentation.enable = lib.mkEnableOption "Enables documentation on system.";
        secureBoot.enable = lib.mkEnableOption "Enables secure boot. See sbctl.";
        pipewire.enable = lib.mkEnableOption "Enables pipewire low latency audio setup";
        tor.enable = lib.mkEnableOption "Enables tor along with torsocks";
        home.enable = lib.mkEnableOption "Enables home user";
        server.enable = lib.mkEnableOption "Enables server services";
        ttyonly.enable = lib.mkEnableOption "TTY only, no xserver";
        grub.enable = lib.mkEnableOption "Enables grub instead of systemd-boot";
        workstation.enable = lib.mkEnableOption "Enables workstation services";
      };
    };
  };

  config = {
    environment.systemPackages = lib.mkIf config.monorepo.profiles.documentation.enable (with pkgs; [
      linux-manual
      man-pages
      man-pages-posix
      iproute2
      silver-searcher
      ripgrep
    ]);
    boot.loader.grub = lib.mkIf config.monorepo.profiles.grub.enable {
      enable = true;
    };

    monorepo = {
      profiles = {
        documentation.enable = lib.mkDefault true;
        pipewire.enable = lib.mkDefault true;
        tor.enable = lib.mkDefault true;
        home.enable = lib.mkDefault true;
      };
    };
  };
}

6.3. X11

My Xorg configuration is used as a backup for when wayland applications don't work. Note that using this configuration is extremely inefficient and my i3 configuration is unoptimized. Still, it is suitable for using Krita.

{ lib, config, pkgs, ... }:
{
  services.xserver = {
    enable = (! config.monorepo.profiles.ttyonly.enable);
    displayManager = {
      startx.enable = (! config.monorepo.profiles.ttyonly.enable);
    };

    windowManager = {
      i3 = {
        enable = ! config.monorepo.profiles.ttyonly.enable;
        package = pkgs.i3-gaps;
      };
    };

    desktopManager = {
      runXdgAutostartIfNone = true;
    };

    xkb = {
      layout = "us";
      variant = "";
      options = "caps:escape";
    };

    videoDrivers = (if config.monorepo.profiles.cuda.enable then [ "nvidia" ] else []);
  };
}

You should add your own video drivers in a custom machine configuration.

6.4. Docker

In order to run docker containers, I need this file:

{ lib, config, vars, ... }:
{
  virtualisation.docker.enable = true;
}

6.5. Pipewire

My low latency pipewire configuration is used for music production, as well as for regular desktop usage. Pipewire is much better than pulseaudio because it supports jack with the same underlying interface and it breaks significantly less often.

{ lib, config, ... }:
{
  services.pipewire = {
    enable = lib.mkDefault config.monorepo.profiles.pipewire.enable;
    alsa = {
      enable = true;
      support32Bit = true;
    };
    pulse.enable = true;
    jack.enable = true;
    wireplumber.enable = true;
    extraConfig = {
      pipewire."92-low-latency" = {
        "context.properties" = {
          "default.clock.rate" = 48000;
          "default.clock.quantum" = 256;
          "default.clock.min-quantum" = 32;
          "default.clock.max-quantum" = 512;
        };
        pipewire-pulse."92-low-latency" = {
          "context.properties" = [
            {
              name = "libpipewire-module-protocol-pulse";
              args = { };
            }
          ];
          "pulse.properties" = {
            "pulse.min.req" = "32/48000";
            "pulse.default.req" = "32/48000";
            "pulse.max.req" = "32/48000";
            "pulse.min.quantum" = "32/48000";
            "pulse.max.quantum" = "32/48000";
          };
          "stream.properties" = {
            "node.latency" = "32/48000";
            "resample.quality" = 1;
          };
        };
      };
    };
  };
}

6.6. SSH

My SSH daemon configuration.

{ config, lib, ... }:
{
  services.openssh = {
    enable = true;
    settings = {
      PasswordAuthentication = lib.mkDefault (! config.monorepo.profiles.server.enable);
      AllowUsers = [ config.monorepo.vars.userName "root" "git" ];
      PermitRootLogin = "prohibit-password";
      KbdInteractiveAuthentication = false;
    };
  };
}

6.7. Tor

This is my tor configuration, used for my cryptocurrency wallets and whatever else I want it to do.

{ config, lib, ... }:
{
  services.tor = {
    enable = lib.mkDefault config.monorepo.profiles.tor.enable;
    openFirewall = true;
    client = {
      enable = lib.mkDefault config.monorepo.profiles.tor.enable;
      socksListenAddress = {
        IsolateDestAddr = true;
        addr = "127.0.0.1";
        port = 9050;
      };
      dns.enable = true;
    };
    torsocks = {
      enable = lib.mkDefault config.monorepo.profiles.tor.enable;
      server = "127.0.0.1:9050";
    };
  };
}

6.8. Kubo IPFS

I use IPFS for my website and also for my ISOs for truly declarative and deterministic configuration. NixOS might be moving to IPFS for binary cache distribution and package distribution soon, and I'm waiting on that.

{ config, pkgs, lib, ... }:
{
  services.kubo = {
    enable = lib.mkDefault config.monorepo.profiles.workstation.enable;
  };
}

6.9. Murmur

{ lib, config, ... }:
{
  services.murmur = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    logFile = "/var/log/murmur.log";
    openFirewall = true;
    hostName = "0.0.0.0";
    welcometext = "Wecome to the Null Murmur instance!";
    registerName = "nullring";
    registerHostname = "nullring.xyz";
    sslCert = "/var/lib/acme/nullring.xyz/fullchain.pem";
    sslKey = "/var/lib/acme/nullring.xyz/sslKey.pem";
  };
}

6.10. i2pd

I use i2p for some p2p connections. We enable it with the server profile:

{ config, lib, ... }:
{
  services.i2pd = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    address = "0.0.0.0";
    inTunnels = {
    };
    outTunnels = {
    };
  };
}

6.11. Icecast

This is an internet radio which will host a ton of music.

{ lib, config, ... }:
{
  services.icecast = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    listen.address = "0.0.0.0";
    extraConfig = ''
<mount type="default">
  <public>0</public>
  <intro>/stream.m3u</intro>
  <max-listener-duration>3600</max-listener-duration>
  <authentication type="url">
    <option name="mount_add" value="http://auth.example.org/stream_start.php"/>
  </authentication>
  <http-headers>
    <header name="foo" value="bar" />
  </http-headers>
</mount>
'';
  };
  admin.password = "changeme";
}

6.12. IRC

A great protocol. It's the most widely usable by any netizen, as it is just pure plaintext and the operating costs are trivial.

6.12.1. NgIRCD

I run my own IRC server to bridge with my Matrix server and my discord guild.

{ lib, config, ... }:
{
  services.ngircd = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    config = ''
[Global]
  Name = nullring.xyz
  Info = NullRing IRC Instance
  Listen = 0.0.0.0
  MotdFile = /etc/motd.txt
  Network = NullRing
  Ports = 6667
[Options]
  PAM = no
[SSL]
  CertFile = /var/lib/acme/nullring.xyz/fullchain.pem
  CipherList = HIGH:!aNULL:@STRENGTH:!SSLv3
  KeyFile = /var/lib/acme/nullring.xyz/key.pem
  Ports = 6697
'';
  };
  environment.etc."motd.txt" = {
    source = ../data/motd.txt;
    mode = "644";
    user = "ngircd";
    group = "ngircd";
  };
}

6.12.2. MOTD

I also have a MOTD file that I want to add, which displays when users connect to the server:

Welcome to the NullRing experience!
The main channel is #nullring; we're glad to have you!

Rules:
1. Don't be annoying.
2. No illegal content.
And if you're here to have constructive, philisophical and theoretical
conversations, this is the place for you!

6.12.3. ZNC

I want to be able to create some sort of identity persistence on IRC for users:

{ lib, config, ... }:
{
  services.znc = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    openFirewall = true;
    confOptions = {
      useSSL = true;
      passBlock = ''
<Pass password>
  Method = sha256
  Hash = d4abdd69aa24de69693885c5bd83a4a0e9ee989e1a69a905041b0dad9abc06ea
  Salt = sDY,?H5AxC-!gH3a.:)D
  Hash = ${config.sops.secrets.znc_password_hash}
  Salt = ${config.sops.secrets.znc_password_salt}
</Pass>
'';
      modules = [
        "partyline"
        "webadmin"
        "adminlog"
        "log"
      ];
      networks = {
        "libera" = {
          server = "irc.libera.chat";
          port = 6697;
          useSSL = true;
          modules = [ "simple_away" ];
        };
      };
    };
  };
}

Note that the password hash and whatnot is completely random so there is almost no point to cracking it with hashcat.

6.13. Conduit

This is a modern matrix server that is meant to be lightweight while still federating and hosting the same protocol.

{ config, lib, ... }:
{
  services.matrix-conduit = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    settings.global = {
      server_name = "matrix.${config.monorepo.vars.remoteHost}";
      trusted_servers = [
        "matrix.org"
        "nixos.org"
      ];
      address = "0.0.0.0";
      port = 6167;
      allow_registration = true;
    };
  };
}

6.14. Matterbridge

Then I want to connect all these servers together with Matterbridge:

{ lib, config, ... }:
{
  services.matterbridge = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    configPath = "/etc/matterbridge.toml";
  };
}

6.15. Ollama

Use ollama for serving large language models to my other computers.

{ config, lib, ... }:
{
  services.ollama = {
    enable = lib.mkDefault (!config.monorepo.profiles.ttyonly.enable);
    acceleration = if (config.monorepo.profiles.workstation.enable) then "cuda" else null;
    loadModels = [
      "qwen3:30b"
      "qwen3-coder:latest"
      "qwen2.5-coder:latest"
      "qwen2.5-coder:3b"
      "gemma3:12b-it-qat"
    ];
    host = "0.0.0.0";
    openFirewall = true;
  };
}

6.16. Bitcoind

{ config, lib, ... }:
{
  services.bitcoind."${config.monorepo.vars.userName}" = {
    enable = lib.mkDefault config.monorepo.profiles.workstation.enable;
    prune = 10000;
  };
}

6.17. Git Server

I run my own git server in order to have a mirror in case github goes down.

{ config, lib, ... }:
{
  services.gitDaemon = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    exportAll = true;
    basePath = "/srv/git";
  };
}

6.18. Nginx

These are all my virtual hosts. For many of these servers we have to have a reverse proxy in order to expose the locally running instances to the outside world under a domain.

{ config, lib, services, ... }:
{
  services.nginx = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    user = "nginx";
    # Use recommended settings
    recommendedGzipSettings = true;
    recommendedOptimisation = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;
    appendHttpConfig = '''';

    gitweb = {
      enable = true;
      virtualHost = "${config.monorepo.vars.remoteHost}";
    };

    virtualHosts = {
      "matrix.${config.monorepo.vars.remoteHost}" = {
        enableACME = true;
        forceSSL = true;
        listen = [
          {
            addr = "0.0.0.0";
            port = 443;
            ssl = true;
          }
          {
            addr = "[::]";
            port = 443;
            ssl = true;
          }          {
            addr = "0.0.0.0";
            port = 8448;
            ssl = true;
          }
          {
            addr = "[::]";
            port = 8448;
            ssl = true;
          }
        ];
        locations."/_matrix/" = {
          proxyPass = "http://127.0.0.1:6167";
          extraConfig = ''
            proxy_set_header Host $host;
            proxy_buffers 32 16k;
            proxy_read_timeout 5m;
          '';
        };

        extraConfig = ''
          merge_slashes off;
        '';
      };
      "${config.monorepo.vars.remoteHost}" = {
        serverName = "${config.monorepo.vars.remoteHost}";
        serverAliases = [ "ret2pop.nullring.xyz" ];
        root = "/var/www/ret2pop-website/";
        addSSL = true;
        enableACME = true;
      };

      "nullring.xyz" = {
        serverName = "nullring.xyz";
        root = "/var/www/nullring/";
        addSSL = true;
        enableACME = true;
      };

      "mail.${config.monorepo.vars.remoteHost}" = {
        serverName = "mail.${config.monorepo.vars.remoteHost}";
        root = "/var/www/dummy";
        addSSL = true;
        enableACME = true;
      };
    };
  };
}

6.19. Git Web Interface

I enable the git web interface to show off my git repos to the world. This was the easiest frontend to set up on NixOS.

{ lib, config, ... }:
{
  services.gitweb = {
    gitwebTheme = true;
    projectroot = "/srv/git/";
  };
}

6.20. Nvidia

{ config, lib, pkgs, ... }:
{
  hardware = {
    graphics.extraPackages = (if config.monorepo.profiles.cuda.enable
                              then with pkgs; [
                                vaapiVdpau
                                libvdpau-va-gl
                                nvidia-vaapi-driver
                              ] else []);

    nvidia = {
      modesetting.enable = lib.mkDefault config.monorepo.profiles.cuda.enable;
      powerManagement = {
        enable = lib.mkDefault config.monorepo.profiles.cuda.enable;
        finegrained = false;
      };
      nvidiaSettings = lib.mkDefault config.monorepo.profiles.cuda.enable;
      open = lib.mkDefault false;
      package = config.boot.kernelPackages.nvidiaPackages.stable;
    };
  };
}

6.21. CUDA

{ config, lib, pkgs, ... }:
{
  environment.systemPackages = (if config.monorepo.profiles.cuda.enable then with pkgs; [
  cudatoolkit
  cudaPackages.cudnn
  cudaPackages.libcublas
  linuxPackages.nvidia_x11
  ] else []);
}

6.22. Maddy

{ lib, config, options, ... }:
{
  services.maddy = {
    enable = lib.mkDefault config.monorepo.profiles.server.enable;
    openFirewall = true;
    primaryDomain = "ret2pop.net";
    tls = {
      loader = "acme";
    };
    config = builtins.replaceStrings [
      "imap tcp://0.0.0.0:143"
      "submission tcp://0.0.0.0:587"
    ] [
      "imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
      "submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
    ] options.services.maddy.config.default;
  };
}

6.23. Main Configuration

This is the backbone of the all the NixOS configurations, with all these options being shared because they enhance security.

{ config, pkgs, lib, ... }:
{
  imports = [
    ./matterbridge.nix
    ./xserver.nix
    ./ssh.nix
    ./pipewire.nix
    ./tor.nix
    ./kubo.nix
    ./nvidia.nix
    ./cuda.nix
    ./nginx.nix
    ./git-daemon.nix
    ./ollama.nix
    ./i2pd.nix
    ./gitweb.nix
    ./conduit.nix
    ./bitcoin.nix
    ./murmur.nix
    ./ngircd.nix
    ./znc.nix
    ./docker.nix
  ];

  documentation = {
    enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
    man.enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
    dev.enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
  };

  environment = {
    etc = {
      securetty.text = ''
        # /etc/securetty: list of terminals on which root is allowed to login.
        # See securetty(5) and login(1).
        '';
    };
  };

  systemd = {
    coredump.enable = false;
    network.config.networkConfig.IPv6PrivacyExtensions = "kernel";
    tmpfiles.settings = {
      "restricthome"."/home/*".Z.mode = "~0700";

      "restrictetcnixos"."/etc/nixos/*".Z = {
        mode = "0000";
        user = "root";
        group = "root";
      };
    };
  };


  boot = {

    extraModprobeConfig = ''
  options snd-usb-audio vid=0x1235 pid=0x8200 device_setup=1
'';
    extraModulePackages = [ ];

    initrd = {
      availableKernelModules = [
        "xhci_pci"
        "ahci"
        "usb_storage"
        "sd_mod"
        "nvme"
        "sd_mod"
        "ehci_pci"
        "rtsx_pci_sdmmc"
        "usbhid"
      ];

      kernelModules = [ ];
    };

    lanzaboote = {
      enable = config.monorepo.profiles.secureBoot.enable;
      pkiBundle = "/etc/secureboot";
    };

    loader = {
      systemd-boot.enable = lib.mkForce (! config.monorepo.profiles.grub.enable);
      efi.canTouchEfiVariables = lib.mkForce (! config.monorepo.profiles.grub.enable);
    };

    kernelModules = [
      "snd-seq"
      "snd-rawmidi"
      "xhci_hcd"
      "kvm_intel"
    ];

    kernelParams = [
      "usbcore.autosuspend=-1"
      "debugfs=off"
      "page_alloc.shuffle=1"
      "slab_nomerge"
      "page_poison=1"

      # madaidan
      "pti=on"
      "randomize_kstack_offset=on"
      "vsyscall=none"
      "module.sig_enforce=1"
      "lockdown=confidentiality"

      # cpu
      "spectre_v2=on"
      "spec_store_bypass_disable=on"
      "tsx=off"
      "l1tf=full,force"
      "kvm.nx_huge_pages=force"

      # hardened
      "extra_latent_entropy"

      # mineral
      "init_on_alloc=1"
      "random.trust_cpu=off"
      "random.trust_bootloader=off"
      "intel_iommu=on"
      "amd_iommu=force_isolation"
      "iommu=force"
      "iommu.strict=1"
      "init_on_free=1"
      "quiet"
      "loglevel=0"
    ];

    blacklistedKernelModules = [
      "netrom"
      "rose"

      "adfs"
      "affs"
      "bfs"
      "befs"
      "cramfs"
      "efs"
      "erofs"
      "exofs"
      "freevxfs"
      "f2fs"
      "hfs"
      "hpfs"
      "jfs"
      "minix"
      "nilfs2"
      "ntfs"
      "omfs"
      "qnx4"
      "qnx6"
      "sysv"
      "ufs"
    ];

    kernel.sysctl = {
      "kernel.ftrace_enabled" = false;
      "net.core.bpf_jit_enable" = false;
      "kernel.kptr_restrict" = 2;

      # madaidan
            "kernel.smtcontrol" = "on";
      "vm.swappiness" = 1;
      "vm.unprivileged_userfaultfd" = 0;
      "dev.tty.ldisc_autoload" = 0;
      "kernel.kexec_load_disabled" = 1;
      "kernel.sysrq" = 4;
      "kernel.perf_event_paranoid" = 3;

      # net
      "net.ipv4.icmp_echo_ignore_broadcasts" = true;

      "net.ipv4.conf.all.accept_redirects" = false;
      "net.ipv4.conf.all.secure_redirects" = false;
      "net.ipv4.conf.default.accept_redirects" = false;
      "net.ipv4.conf.default.secure_redirects" = false;
      "net.ipv6.conf.all.accept_redirects" = false;
      "net.ipv6.conf.default.accept_redirects" = false;
    };
  };

  networking = {
    useDHCP = lib.mkDefault true;
    networkmanager = {
      enable = true;
    };
    firewall = {
      allowedTCPPorts = [ 22 11434 ];
      allowedUDPPorts = [ ];
    };
  };

  hardware = {
    enableAllFirmware = true;
    cpu.intel.updateMicrocode = true;
    graphics.enable = ! config.monorepo.profiles.ttyonly.enable;

    bluetooth = {
      enable = true;
      powerOnBoot = true;
    };
  };

  services = {
    pulseaudio.enable = ! config.monorepo.profiles.pipewire.enable;
    chrony = {
      enable = true;
      enableNTS = true;
      servers = [ "time.cloudflare.com" "ptbtime1.ptb.de" "ptbtime2.ptb.de" ];
    };

    jitterentropy-rngd.enable = true;
    resolved.dnssec = true;
    # usbguard.enable = true;
    usbguard.enable = false;
    dbus.apparmor = "enabled";

    kanata.enable = true;

    # Misc.
    udev = {
      extraRules = '''';
      packages = with pkgs; [ 
        platformio-core
        platformio-core.udev
        openocd
      ];
    };

    printing.enable = true;
    udisks2.enable = true;
  };

  programs = {
    nix-ld.enable = true;
    zsh.enable = true;
    light.enable = true;
    ssh.enableAskPassword = false;
  };

  nixpkgs = {
    hostPlatform = lib.mkDefault "x86_64-linux";
    config = {
      allowUnfree = true;
      cudaSupport = lib.mkDefault config.monorepo.profiles.cuda.enable;
    };
  };

  security = {
    acme = {
      acceptTerms = true;
      defaults.email = "ret2pop@gmail.com";
    };
    apparmor = {
      enable = true;
      killUnconfinedConfinables = true;
    };

    pam.loginLimits = [
      { domain = "*"; item = "nofile"; type = "-"; value = "32768"; }
      { domain = "*"; item = "memlock"; type = "-"; value = "32768"; }
    ];
    rtkit.enable = true;

    lockKernelModules = true;
    protectKernelImage = true;
    allowSimultaneousMultithreading = true;
    forcePageTableIsolation = true;

    tpm2 = {
      enable = true;
      pkcs11.enable = true;
      tctiEnvironment.enable = true;
    };

    auditd.enable = true;
    audit.enable = true;
    chromiumSuidSandbox.enable = (! config.monorepo.profiles.ttyonly.enable);
    sudo.enable = true;
  };

  xdg.portal = {
    enable = (! config.monorepo.profiles.ttyonly.enable);
    wlr.enable = true;
    extraPortals = with pkgs; if (! config.monorepo.profiles.ttyonly.enable) then [
      xdg-desktop-portal-gtk
      xdg-desktop-portal
      xdg-desktop-portal-hyprland
    ] else [];
    config.common.default = "*";
  };

  environment.etc."gitconfig".text = ''
  [init]
  defaultBranch = main
  '';
  environment.extraInit = ''
  umask 0022
  '';
  environment.systemPackages = with pkgs; [
    restic
    sbctl
    git
    vim
    curl
    nmap
    (writeShellScriptBin "new-repo"
      ''
  #!/bin/bash
  cd /srv/git
  git init --bare "$1"
  vim "$1/description"
  chown -R git:git "$1"
  ''
    )
  ];

  users.groups.nginx = lib.mkDefault {};
  users.groups.git = lib.mkDefault {};
  users.groups.ircd = lib.mkDefault {};
  users.groups.ngircd = lib.mkDefault {};

  users.users = {

    ngircd = {
      isSystemUser = lib.mkDefault true;
      group = "ngircd";
      extraGroups = [ "acme" "nginx" ];
    };

    ircd = {
      isSystemUser = lib.mkDefault true;
      group = "ircd";
      home = "/home/ircd";
    };

    nginx = {
      group = "nginx";
      isSystemUser = lib.mkDefault true;
      extraGroups = [
        "acme"
      ];
    };

    root.openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell"
    ];

    git = {
      isSystemUser = true;
      home = "/srv/git";
      shell = "${pkgs.git}/bin/git-shell";
      group = "git";
      openssh.authorizedKeys.keys = [
        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell"
      ];
    };
    "${config.monorepo.vars.userName}" = {
      openssh.authorizedKeys.keys = [
        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell"
      ];

      initialPassword = "${config.monorepo.vars.userName}";
      isNormalUser = true;
      description = config.monorepo.vars.fullName;
      extraGroups = [ "networkmanager" "wheel" "video" "docker" "jackaudio" "tss" "dialout" "docker" ];
      shell = pkgs.zsh;
      packages = [];
    };
  };

  nixpkgs.config.permittedInsecurePackages = [
    "olm-3.2.16"
  ];

  nix = {
    settings = {
      experimental-features = "nix-command flakes";
      trusted-users = [ "@wheel" ];
    };
  };
  time.timeZone = config.monorepo.vars.timeZone;
  i18n.defaultLocale = "en_CA.UTF-8";
  system.stateVersion = "24.11";
}

6.24. Disko

This is the disko configuration for my continuity system. It features a boot and ext4 partition, with configurable disk.

6.24.1. Btrfs

{ lib, config, ... }:
let
  spec = {
  disko.devices = {
    disk = {
      main = {
        type = "disk";
        device = config.monorepo.vars.device;
        content = {
          type = "gpt";
          partitions = {
            ESP = {
              priority = 1;
              name = "ESP";
              start = "1M";
              end = "128M";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = [ "umask=0077" ];
              };
            };
            root = {
              size = "100%";
              content = {
                type = "btrfs";
                extraArgs = [ "-f" ]; # Override existing partition
                mountpoint = "/";
                mountOptions = [
                  "compress=zstd"
                  "noatime"
                ];
              };
            };
          };
        };
      };
    };
  };
};
in
{
  monorepo.vars.diskoSpec = spec;
  disko.devices = spec.disko.devices;
}

6.24.2. Simple

This configuration is used for simple partitioning schemes with EFI.

{ lib, config, ... }:
let
  spec = {
    disko.devices = {
      disk = {
        my-disk = {
          device = config.monorepo.vars.device;
          type = "disk";
          content = {
            type = "gpt";
            partitions = {
              ESP = {
                type = "EF00";
                size = "500M";
                priority = 1;
                content = {
                  type = "filesystem";
                  format = "vfat";
                  mountpoint = "/boot";
                  mountOptions = [ "umask=0077" ];
                };
              };
              root = {
                size = "100%";
                priority = 2;
                content = {
                  type = "filesystem";
                  format = "ext4";
                  mountpoint = "/";
                };
              };
            };
          };
        };
      };
    };
  };
in
{
  monorepo.vars.diskoSpec = spec;
  disko.devices = spec.disko.devices;
}

6.24.3. BIOS

For machines that use BIOS instead of EFI.

{ config, lib, ... }:
let
  spec = {
    disko.devices = {
      disk = {
        main = {
          device = config.monorepo.vars.device;
          type = "disk";
          content = {
            type = "gpt";
            partitions = {
              boot = {
                size = "1M";
                type = "EF02";
              };
              root = {
                label = "disk-main-root"; 
                size = "100%";
                content = {
                  type = "filesystem";
                  format = "ext4";
                  mountpoint = "/";
                };
              };
            };
          };
        };
      };
    };
  };
in
{
  monorepo.vars.diskoSpec = spec;
  disko.devices = spec.disko.devices;
}

6.25. Home

6.25.1. Default Home Profile

As you can see, I have my installed home packages installed based on the profiles enabled. Also, I have many imports that we'll go through next.

{ lib, config, pkgs, sops-nix, ... }:
{
  imports = [
    sops-nix.homeManagerModules.sops
    ../vars.nix
    ./fcitx.nix
    ./secrets.nix
    ./emacs.nix
    ./firefox.nix
    ./git.nix
    ./hyprland.nix
    ./mpv.nix
    ./yt-dlp.nix
    ./wofi.nix
    ./kitty.nix
    ./waybar.nix
    ./zsh.nix
    ./mbsync.nix
    ./msmtp.nix
    ./gammastep.nix
    ./mpd.nix
    ./mako.nix
    ./user.nix
  ];

  options = {
    monorepo.profiles = {
      enable = lib.mkEnableOption "Enables home manager desktop configuration";
      # Programs
      graphics.enable = lib.mkEnableOption "Enables graphical programs for user";
      lang-c.enable = lib.mkEnableOption "Enables C language support";
      lang-sh.enable = lib.mkEnableOption "Enables sh language support";
      lang-rust.enable = lib.mkEnableOption "Enables Rust language support";
      lang-python.enable = lib.mkEnableOption "Enables python language support";
      lang-sol.enable = lib.mkEnableOption "Enables solidity language support";
      lang-openscad.enable = lib.mkEnableOption "Enables openscad language support";
      lang-js.enable = lib.mkEnableOption "Enables javascript language support";
      lang-nix.enable = lib.mkEnableOption "Enables nix language support";
      lang-coq.enable = lib.mkEnableOption "Enables coq language support";
      lang-lean.enable = lib.mkEnableOption "Enables lean language support";
      lang-haskell.enable = lib.mkEnableOption "Enables haskell language support";

      crypto.enable = lib.mkEnableOption "Enables various cryptocurrency wallets";
      art.enable = lib.mkEnableOption "Enables various art programs";
      music.enable = lib.mkEnableOption "Enables mpd";
      workstation.enable = lib.mkEnableOption "Enables workstation packages (music production and others)";
      cuda.enable = lib.mkEnableOption "Enables CUDA user package builds";
      hyprland.enable = lib.mkEnableOption "Enables hyprland";

      email = {
        email = lib.mkOption {
          type = lib.types.str;
          default = "ret2pop@gmail.com";
          example = "john@example.com";
          description = "Email address and imaps/smtps account";
        };
        imapsServer = lib.mkOption {
          type = lib.types.str;
          default = "imap.gmail.com";
          example = "imap.example.com";
          description = "imaps server address";
        };
        smtpsServer = lib.mkOption {
          type = lib.types.str;
          default = "smtp.gmail.com";
          example = "smtp.example.com";
          description = "smtp server address";
        };
        enable = lib.mkEnableOption "Enables email";
      };
    };
  };

  config = {
    home.packages = (if config.monorepo.profiles.email.enable then [ pkgs.mu ] else [])
                    ++
                    (if config.monorepo.profiles.lang-c.enable then (with pkgs; [
                      autobuild
                      clang
                      gdb
                      gnumake
                      bear
                      clang-tools
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.workstation.enable then (with pkgs; [
                      mumble
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-js.enable then (with pkgs; [
                      nodejs
                      bun
                      yarn
                      typescript
                      typescript-language-server
                      vscode-langservers-extracted
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-rust.enable then (with pkgs; [
                      cargo
                      rust-analyzer
                      rustfmt
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-python.enable then (with pkgs; [
                      poetry
                      python3
                      python312Packages.jedi
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-sol.enable then (with pkgs; [
                      solc
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-openscad.enable then (with pkgs; [
                      openscad
                      openscad-lsp
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-sh.enable then (with pkgs; [
                      bash-language-server
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-haskell.enable then (with pkgs; [
                      haskell-language-server
                      haskellPackages.hlint
                      ghc
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-coq.enable then (with pkgs; [
                      coq
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-lean.enable then (with pkgs; [
                      lean4
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-nix.enable then (with pkgs; [
                      nil
                      nixd
                      nixfmt-rfc-style
                      nix-prefetch-scripts
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.crypto.enable then (with pkgs; [
                      bitcoin
                      electrum
                      monero-cli
                      monero-gui
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.art.enable then (with pkgs; [
                      inkscape
                      # krita
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.music.enable then (with pkgs; [
                      mpc-cli
                      sox
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.workstation.enable then (with pkgs; [
                      alsa-utils
                      alsa-scarlett-gui
                      ardour
                      audacity
                      # blender
                      foxdot
                      fluidsynth
                      qjackctl
                      qsynth
                      qpwgraph
                      imagemagick
                      supercollider
                      inkscape
                      kdePackages.kdenlive
                      # kicad
                      murmur
                    ]) else []);

    monorepo.profiles = {
      enable = lib.mkDefault true;
      music.enable = lib.mkDefault config.monorepo.profiles.enable;
      hyprland.enable = lib.mkDefault config.monorepo.profiles.enable;
      email.enable = lib.mkDefault config.monorepo.profiles.enable;

      # Programming
      graphics.enable = lib.mkDefault  config.monorepo.profiles.enable;
      lang-c.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-rust.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-python.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-sol.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-sh.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-openscad.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-js.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-nix.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-coq.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-lean.enable = lib.mkDefault config.monorepo.profiles.enable;
      lang-haskell.enable = lib.mkDefault config.monorepo.profiles.enable;

      crypto.enable = lib.mkDefault config.monorepo.profiles.enable;
      art.enable = lib.mkDefault config.monorepo.profiles.enable;
      workstation.enable = lib.mkDefault config.monorepo.profiles.enable;
    };
  };
}

6.25.2. Firefox

I conditionally enable metamask based on the cryptocurrency option. Everything else here should be straightforward.

{ lib, config, pkgs, ... }:
{
  programs.firefox = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    package = pkgs.firefox-bin;
    policies = {
      EnableTrackingProtection = true;
      OfferToSaveLogins = false;
    };
    profiles = {
      default = {
        id = 0;
        name = "default";
        isDefault = true;

        extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
          ublock-origin
          tree-style-tab
          firefox-color
          vimium
        ]
        ++ (lib.optional
          config.monorepo.profiles.crypto.enable pkgs.nur.repos.rycee.firefox-addons.metamask);

        settings = {
          media = {
            memory_cache_max_size = 65536;
            cache_readahead_limit = 7200;
            cache_resume_threshold = 3600;
            peerconnection.ice = {
              proxy_only_if_behind_proxy = true;
              default_address_only = true;
            };
          };

          gfx = {
            content.skia-font-cache-size = 20;
            canvas.accelerated = {
              cache-items = 4096;
              cache-size = 512;
            };
          };

          network = {
            http = {
              max-connections = 1800;
              max-persistent-connections-per-server = 10;
              max-urgent-start-excessive-connections-per-host = 5;
              referer.XOriginTrimmingPolicy = 2;
            };

            buffer.cache = {
              size = 262144;
              count = 128;
            };

            dns = {
              max_high_priority_threads = 8;
              disablePrefetch = true;
            };

            pacing.requests.enabled = false;
            dnsCacheExpiration = 3600;
            ssl_tokens_cache_capacity = 10240;
            prefetch-next = false;
            predictor.enabled = false;
            cookie.sameSite.noneRequiresSecure = true;
            IDN_show_punycode = true;
            auth.subresource-http-auth-allow = 1;
            captive-portal-service.enabled = false;
            connectivity-service.enabled = false;
          };

          browser = {
            download = {
              always_ask_before_handling_new_types = true;
              manager.addToRecentDocs = false;
              open_pdf_attachments_inline = true;
              start_downloads_in_tmp_dir = true;
            };

            urlbar = {
              suggest.quicksuggest.sponsored = false;
              suggest.quicksuggest.nonsponsored = false;
              suggest.calculator = true;
              update2.engineAliasRefresh = true;
              unitConversion.enabled = true;
              trending.featureGate = false;
            };

            search = {
              separatePrivateDefault.ui.enabled = true;
              suggest.enabled = false;
            };

            newtabpage.activity-stream = {
              feeds = {
                topsites = false;
                section.topstories = false;
                telemetry = false;
              };
              asrouter.userprefs.cfr = {
                addons = false;
                features = false;
              };
              telemetry = false;
            };

            privatebrowsing = {
              vpnpromourl = "";
              forceMediaMemoryCache = true;
            };

            display = {
              focus_ring_on_anything = true;
              focus_ring_style = 0;
              focus_ring_width = 0;
            };

            cache.jsbc_compression_level = 3;
            helperApps.deleteTempFileOnExit = true;
            uitour.enabled = false;
            sessionstore.interval = 60000;
            formfill.enable = false;
            xul.error_pages.expert_bad_cert = true;
            contentblocking.category = "strict";
            ping-centre.telemetry = false;
            discovery.enabled = false;
            shell.checkDefaultBrowser = false;
            preferences.moreFromMozilla = false;
            tabs.tabmanager.enabled = false;
            aboutConfig.showWarning = false;
            aboutwelcome.enabled = false;
            bookmarks.openInTabClosesMenu = false;
            menu.showViewImageInfo = true;
            compactmode.show = true;
            safebrowsing.downloads.remote.enabled = false;
            tabs.crashReporting.sendReport = false;
            crashReports.unsubmittedCheck.autoSubmit2 = false;
            privateWindowSeparation.enabled = false;
          };

          security = {
            mixed_content = {
              block_display_content = true;
              upgrade_display_content = true;
            };
            insecure_connection_text = {
              enabled = true;
              pbmode.enabled = true;
            };
            OCSP.enabled = 0;
            remote_settings.crlite_filters.enabled = true;
            pki.crlite_mode = 2;
            ssl.treat_unsafe_negotiation_as_broken = true;
            tls.enable_0rtt_data = false;
          };

          toolkit = {
            telemetry = {
              unified = false;
              enabled = false;
              server = "data:,";
              archive.enabled = false;
              newProfilePing.enabled = false;
              shutdownPingSender.enabled = false;
              updatePing.enabled = false;
              bhrPing.enabled = false;
              firstShutdownPing.enabled = false;
              coverage.opt-out = true;
            };
            coverage = {
              opt-out = true;
              endpoint.base = "";
            };
            legacyUserProfileCustomizations.stylesheets = true;
          };

          dom = {
            security = {
              https_first = true;
              https_first_schemeless = true;
              sanitizer.enabled = true;
            };
            enable_web_task_scheduling = true;
          };

          layout = {
            css = {
              grid-template-masonry-value.enabled = true;
              has-selector.enabled = true;
              prefers-color-scheme.content-override = 2;
            };
            word_select.eat_space_to_next_word = false;
          };

          urlclassifier = {
            trackingSkipURLs = "*.reddit.com, *.twitter.com, *.twimg.com, *.tiktok.com";
            features.socialtracking.skipURLs = "*.instagram.com, *.twitter.com, *.twimg.com";
          };

          privacy = {
            globalprivacycontrol.enabled = true;
            history.custom = true;
            userContext.ui.enabled = true;
            trackingprotection = {
              enabled = true;
              pbmode.enabled = true;
              socialtracking.enabled = true;
            };
          };

          full-screen-api = {
            transition-duration = {
              enter = "0 0";
              leave = "0 0";
            };
            warning = {
              delay = -1;
              timeout = 0;
            };
          };

          permissions.default = {
            desktop-notification = 2;
            geo = 2;
          };

          signon = {
            formlessCapture.enabled = false;
            privateBrowsingCapture.enabled = false;
          };

          datareporting = {
            policy.dataSubmissionEnabled = false;
            healthreport.uploadEnabled = false;
          };

          extensions = {
            pocket.enabled = false;
            getAddons.showPane = false;
            htmlaboutaddons.recommendations.enabled = false;
            postDownloadThirdPartyPrompt = false;
          };

          app = {
            shield.optoutstudies.enabled = false;
            normandy.enabled = false;
            normandy.api_url = "";
          };

          image.mem.decode_bytes_at_a_time = 32768;
          editor.truncate_user_pastes = false;
          pdfjs.enableScripting = false;
          geo.provider.network.url = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%";
          permissions.manager.defaultsUrl = "";
          webchannel.allowObject.urlWhitelist = "";
          breakpad.reportURL = "";
          captivedetect.canonicalURL = "";
          cookiebanners.service.mode = 1;
          findbar.highlightAll = true;
          content.notify.interval = 100000;
        };
      };
    };
  };
}

6.25.3. Fcitx

This is a virtual keyboard program for writing in multiple languages. I use this sometimes.

{ config, pkgs, lib, ... }:
{
  i18n.inputMethod = {
    type = "fcitx5";
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    fcitx5.addons = with pkgs; [
      fcitx5-gtk
      fcitx5-chinese-addons
      fcitx5-configtool
      fcitx5-mozc
      fcitx5-rime
    ];
  };
}

Note that I configure fcitx with chinese and some japanese input enabled.

6.25.4. Emacs

I install all my emacs packages within Nix so that they build deterministically with native compilation, and because I can fetch their exact versions. Note that I have a stub configuration here that tells emacs to load my real configuration at ~/monorepo/config/emacs.org as an org file which gets automatically tangled to an emacs-lisp file.

{ lib, config, pkgs, ... }:
{
  programs.emacs = 
    {
      enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
      package = pkgs.emacs-pgtk;
      extraConfig = ''
      (setq debug-on-error t)
      (org-babel-load-file
        (expand-file-name "~/monorepo/config/emacs.org"))'';
      extraPackages = epkgs: [
        epkgs.all-the-icons
        epkgs.auctex
        epkgs.catppuccin-theme
        epkgs.chatgpt-shell
        epkgs.company
        epkgs.company-solidity
        epkgs.counsel
        epkgs.dashboard
        epkgs.doom-modeline
        epkgs.elfeed
        epkgs.elfeed-org
        epkgs.elfeed-tube
        epkgs.elfeed-tube-mpv
        epkgs.ellama
        epkgs.elpher
        epkgs.ement
        epkgs.emmet-mode
        epkgs.emms
        epkgs.enwc
        epkgs.evil
        epkgs.evil-collection
        epkgs.evil-commentary
        epkgs.evil-org
        epkgs.f
        epkgs.flycheck
        epkgs.general
        epkgs.gptel
        epkgs.gruvbox-theme
        epkgs.haskell-mode
        epkgs.htmlize
        epkgs.irony-eldoc
        epkgs.ivy
        epkgs.ivy-pass
        epkgs.kiwix
        epkgs.latex-preview-pane
        epkgs.lsp-ivy
        epkgs.lsp-mode
        epkgs.lsp-haskell
        epkgs.lyrics-fetcher
        epkgs.magit
        epkgs.magit-delta
        epkgs.mu4e
        epkgs.minuet
        epkgs.nix-mode
        epkgs.org-fragtog
        epkgs.org-journal
        epkgs.org-roam
        epkgs.org-roam-ui
        epkgs.org-superstar
        epkgs.page-break-lines
        epkgs.password-store
        epkgs.pdf-tools
        epkgs.pinentry
        epkgs.platformio-mode
        epkgs.projectile
        epkgs.rustic
        epkgs.scad-mode
        epkgs.simple-httpd
        epkgs.solidity-flycheck
        epkgs.solidity-mode
        epkgs.sudo-edit
        epkgs.treemacs
        epkgs.treemacs-evil
        epkgs.treemacs-magit
        epkgs.treemacs-projectile
        epkgs.treesit-auto
        epkgs.typescript-mode
        epkgs.unicode-fonts
        epkgs.use-package
        epkgs.vterm
        epkgs.wgrep
        epkgs.web-mode
        epkgs.websocket
        epkgs.which-key
        epkgs.writegood-mode
        epkgs.writeroom-mode
        epkgs.yaml-mode
        epkgs.yasnippet
        epkgs.yasnippet-snippets
      ];
    };
}

6.25.5. Gammastep

This is a program like redshift for making your screen emit more red and less blue light. Here I have the long and lat set for Vancouver, but you should replace it if you live outside the timezone.

{ lib, config, ... }:
{
  services.gammastep = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    provider = "manual";
    latitude = 49.282730;
    longitude = -123.120735;

    temperature = {
      day = 5000;
      night = 3000;
    };

    settings = {
      general = {
        adjustment-method = "wayland";
      };
    };
  };
}

6.25.6. Git

My git configuration uses information set in the vars.nix in order to set configuration options. Make sure those are set correctly. I've set it to sign by default.

{ lib, config, ... }:
{
  programs.git = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    userName = config.monorepo.vars.fullName;
    userEmail = config.monorepo.profiles.email.email;
    signing = {
      key = config.monorepo.vars.gpgKey;
      signByDefault = true;
    };

    extraConfig = {
      init.defaultBranch = "main";
    };

    aliases = {
      co = "checkout";
      c = "commit";
      a = "add";
      s = "switch";
      b = "branch";
    };
  };
}

6.25.7. Hyprland

My compositor/window manager. This automatically starts on startup. Instructions on how to use this component will come soon.

{ lib, config, wallpapers, pkgs, scripts, ... }:
{
  wayland.windowManager.hyprland = {
    enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
    package = pkgs.hyprland;
    xwayland.enable = true;
    systemd.enable = true;
    settings = {
      "$mod" = "SUPER";
      bezier = [
        "overshot,0,1,0,0.95"
      ];
      animation = [
        "workspaces, 1, 10, overshot"
      ];
      exec-once = [
        "waybar"
        "swww-daemon --format xrgb"
        "swww img ${wallpapers}/imagination.png"
        "fcitx5-remote -r"
        "fcitx5 -d --replace"
        "fcitx5-remote -r"
        "emacs"
        "firefox"
      ];
      env = [
        "LIBVA_DRIVER_NAME,nvidia"
        "XDG_SESSION_TYPE,wayland"
        "GBM_BACKEND,nvidia-drm"
        "__GLX_VENDOR_LIBRARY_NAME,nvidia"
        "ELECTRON_OZONE_PLATFORM_HINT,auto"
      ];
      blurls = [
        "waybar"
      ];
      monitor = [
        "Unknown-1,disable"
      ];
      windowrulev2 = [
        "workspace 1, class:^(emacs)$"
        "workspace 2, class:^(firefox)$"
        "workspace 2, title:^(.*Tor Browser.*)$"
        "workspace 2, title:^(.*Chromium-browser.*)$"
        "workspace 2, class:^(chromium)$"
        "workspace 3, class:^(discord)$"
        "workspace 3, class:^(vesktop)$"
        "workspace 3, title:^(.*fluffychat.*)$"
        "workspace 3, class:^(.*element-desktop.*)$"
        "workspace 4, class:^(.*qpwgraph.*)$"
        "workspace 4, class:^(.*mpv.*)$"
        "workspace 5, title:^(.*Monero.*)$"
        "workspace 5, title:^(.*org\.bitcoin\..*)$"
        "workspace 5, title:^(.*Bitcoin Core - preston.*)$"
        "workspace 5, title:^(.*org\.getmonero\..*)$"
        "workspace 5, title:^(.*Monero - preston.*)$"
        "workspace 5, title:^(.*electrum.*)$"
        "pseudo,title:fcitx"
      ];
      bind = [
        "$mod, F, exec, firefox"
        "$mod, T, exec, tor-browser"
        "$mod, Return, exec, kitty"
        "$mod, E, exec, emacs"
        "$mod, B, exec, bitcoin-qt"
        "$mod, M, exec, monero-wallet-gui"
        "$mod, V, exec, vesktop"
        "$mod, D, exec, wofi --show run"
        "$mod, P, exec, bash ${scripts}/powermenu.sh"
        "$mod, Q, killactive"
        "$mod SHIFT, H, movewindow, l"
        "$mod SHIFT, L, movewindow, r"
        "$mod SHIFT, K, movewindow, u"
        "$mod SHIFT, J, movewindow, d"
        "$mod, H, movefocus, l"
        "$mod, L, movefocus, r"
        "$mod, K, movefocus, u"
        "$mod, J, movefocus, d"
        ", XF86AudioPlay, exec, mpc toggle"
        ", Print, exec, grim"
      ]
      ++ (
        builtins.concatLists (builtins.genList
          (
            x:
            let
              ws =
                let
                  c = (x + 1) / 10;
                in
                  builtins.toString (x + 1 - (c * 10));
            in
              [
                "$mod, ${ws}, workspace, ${toString (x + 1)}"
                "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}"
              ]
          )
          10)
      );
      bindm = [
        "$mod, mouse:272, movewindow"
        "$mod, mouse:273, resizewindow"
        "$mod ALT, mouse:272, resizewindow"
      ];
      binde = [
        ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
        ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"
        ", XF86AudioNext, exec, mpc next"
        ", XF86AudioPrev, exec, mpc prev"
        ", XF86MonBrightnessUp , exec, xbacklight -inc 10"
        ", XF86MonBrightnessDown, exec, xbacklight -dec 10"
      ];
      decoration = {
        blur = {
          enabled = true;
          size = 5;
          passes = 2;
        };
        rounding = 5;
      };
      device = {
        name = "beken-usb-gaming-mouse-1";
        sensitivity = -0.5;
      };
      input = {
        kb_options = "caps:swapescape";
        repeat_delay = 300;
        repeat_rate = 50;
        natural_scroll = true;
        touchpad = {
          natural_scroll = true;
          disable_while_typing = true;
          tap-to-click = true;
        };
      };
      cursor = {
        no_hardware_cursors = true;
      };
      misc = {
        force_default_wallpaper = 0;
        disable_hyprland_logo = true;
      };
    };
  };
}

6.25.8. Kitty

I've set my terminal, kitty, to use catppuccin colors.

{ lib, config, ... }:
{
  programs.kitty = {
    enable = lib.mkDefault (config.monorepo.profiles.hyprland.enable && config.monorepo.profiles.graphics.enable);
    settings = {
      enable_audio_bell = false;
      font_family = "Iosevka Nerd Font";
      font_size = 14;
      confirm_os_window_close = 0;
      background_opacity = "0.9";
      # Catppuccin theme
      foreground = "#cdd6f4";
      background = "#1e1e2e";
      selection_foreground = "#1e1e2e";
      selection_background = "#f5e0dc";
      cursor = "#f5e0dc";
      cursor_text_color = "#1e1e2e";
      url_color = "#f5e0dc";
      active_border_color = "#B4BEFE";
      inactive_border_color = "#6C7086";
      bell_border_color = "#F9E2AF";
      wayland_titlebar_color = "#1E1E2E";
      macos_titlebar_color = "#1E1E2E";
      active_tab_foreground = "#11111B";
      active_tab_background = "#CBA6F7";
      inactive_tab_foreground = "#CDD6F4";
      inactive_tab_background = "#181825";
      tab_bar_background = "#11111B";
      mark1_foreground = "#1E1E2E";
      mark1_background = "#B4BEFE";
      mark2_foreground = "#1E1E2E";
      mark2_background = "#CBA6F7";
      mark3_foreground = "#1E1E2E";
      mark3_background = "#74C7EC";
      color0 = "#45475A";
      color8 = "#585B70";
      color1 = "#F38BA8";
      color9 = "#F38BA8";
      color2 = "#A6E3A1";
      color10 = "#A6E3A1";
      color3 = "#F9E2AF";
      color11 = "#F9E2AF";
      color4 = "#89B4FA";
      color12 = "#89B4FA";
      color5 = "#F5C2E7";
      color13 = "#F5C2E7";
      color6 = "#94E2D5";
      color14 = "#94E2D5";
      color7 = "#BAC2DE";
      color15 = "#A6ADC8";
    };
  };
}

6.25.9. Mako

This is my notification system. My flake automatically fetches the notification sound, so you are all set from the get-go!

{ lib, config, sounds, ... }:
{
  services.mako = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    settings = {
      on-notify = "exec mpv ${sounds}/polite.ogg --no-config --no-video";
      background-color = "#11111bf8";
      text-color = "#cdd6f4";
      border-color = "#89b4faff";
      border-radius = 1;
      font = "Fira Code 10";
      default-timeout = 3000;
    };
  };
}

6.25.10. Mbsync

Note that in order to use my email configuration, your imaps and smtps servers must be encrypted. This module uses the vars.nix as well as the home default.nix options.

{ lib, config, ... }:
{
  programs.mbsync = {
    enable = lib.mkDefault config.monorepo.profiles.email.enable;
    extraConfig = ''
      IMAPAccount ret2pop
      Host ${config.monorepo.profiles.email.imapsServer}
      User ${config.monorepo.profiles.email.email}
      PassCmd "cat ${config.sops.secrets.mail.path}"
      Port 993
      TLSType IMAPS
      AuthMechs *
      CertificateFile /etc/ssl/certs/ca-certificates.crt

      IMAPStore ret2pop-remote
      Account ret2pop

      MaildirStore ret2pop-local
      Path ~/email/ret2pop/
      Inbox ~/email/ret2pop/INBOX
      SubFolders Verbatim

      Channel ret2pop 
      Far :ret2pop-remote:
      Near :ret2pop-local:
      Patterns *
      Create Near
      Sync All
      Expunge None
      SyncState *
    '';
  };
}

6.25.11. MSMTP

This is the program I use to send email from emacs. It is really the same thing as above, just set the options to the ones you want in your system default.nix.

{ lib, config, ... }:
{
  programs.msmtp = {
    enable = lib.mkDefault config.monorepo.profiles.email.enable;
    extraConfig = ''
      # Set default values for all following accounts.
      defaults
      auth           on
      tls            on
      tls_trust_file /etc/ssl/certs/ca-certificates.crt
      tls_certcheck  off
      logfile        ~/.msmtp.log

      # Gmail
      account        ${config.monorepo.vars.userName}
      host           ${config.monorepo.profiles.email.smtpsServer}
      port           587
      from           ${config.monorepo.profiles.email.email}
      user           ${config.monorepo.profiles.email.email}
      passwordeval   "cat ${config.sops.secrets.mail.path}"


      # Set a default account
      account default : ${config.monorepo.vars.userName}
    '';
  };
}

6.25.12. Mpd

This mpd configuration uses pipewire by default, and it should just work if you place music in the ~/music directory and then run mpc add / afterwards.

{ lib, config, ... }:
{
  services.mpd = {
  enable = lib.mkDefault config.monorepo.profiles.music.enable;
  dbFile = "/home/${config.monorepo.vars.userName}/.config/mpd/db";
  dataDir = "/home/${config.monorepo.vars.userName}/.config/mpd/";
  network.port = 6600;
  musicDirectory = "/home/${config.monorepo.vars.userName}/music";
  playlistDirectory = "/home/${config.monorepo.vars.userName}/.config/mpd/playlists";
  network.listenAddress = "0.0.0.0";
  extraConfig = ''
      audio_output {
        type "pipewire"
        name "pipewire output"
      }
      audio_output {
        type    "httpd"
        name    "My HTTP Stream"
        encoder   "opus"    # optional
        port    "8000"
     #  quality   "5.0"     # do not define if bitrate is defined
        bitrate   "128000"      # do not define if quality is defined
        format    "48000:16:1"
        always_on       "yes" # prevent MPD from disconnecting all listeners when playback is stopped.
        tags            "yes" # httpd supports sending tags to listening streams.
      }
audio_output {
    type        "shout"
    encoding    "ogg"
    name        "my cool stream"
    host        "localhost"
    port        "8000"
    mount       "/example.ogg"
    user        "source"
    password    "<source-password>"

    bitrate     "64"
    format      "44100:16:1"
    description "Nullring public radio"
}
    '';
  };
}

6.25.13. MPV

I have some emacs + yt-dlp integrations with mpv with my rss feed, and therefore we need it here:

{ lib, config, ... }:
{
  programs.mpv = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    config = {
      profile = "gpu-hq";
      force-window = true;
      ytdl-format = "bestvideo+bestaudio";
      cache-default = 4000000;
    };
  };
}

6.25.14. Secrets

This uses sops in order to declaratively create the secrets on my system by unencrypting the yaml file specified. Yes, this is safe to include in the repo.

{ config, ... }:
{
  sops = {
    defaultSopsFile = ../../secrets/secrets.yaml;
    age = {
      keyFile = "/home/${config.monorepo.vars.userName}/.ssh/keys.txt";
    };
    secrets = {
      mail = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/mail";
      };
      cloudflare-dns = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/cloudflare-dns";
      };
      digikey = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/digikey";
      };
      dn42 = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/dn42";
      };
      znc = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/znc";
      };
      znc_password_salt = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/znc_password_salt";
      };

      znc_password_hash = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/znc_password_hash";
      };

      matrix_bridge = {
        format = "yaml";
        path = "${config.sops.defaultSymlinkPath}/matrix_bridge";
      };
    };
    defaultSymlinkPath = "/run/user/1000/secrets";
    defaultSecretsMountPoint = "/run/user/1000/secrets.d";
  };
}

6.25.15. Waybar

This is the bar I use for my hyprland configuration. You will need to adjust the monitors field in the default.nix for it to really appear.

{ lib, config, ... }:
{
  programs.waybar = {
    enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
    style = ''
      * {
          border: none;
          border-radius: 0px;
          font-family: Iosevka Nerd Font, FontAwesome, Noto Sans CJK;
          font-size: 14px;
          font-style: normal;
          min-height: 0;
      }

      window#waybar {
          background: rgba(30, 30, 46, 0.5);
          border-bottom: 1px solid #45475a;
          color: #cdd6f4;
      }

      #workspaces {
        background: #45475a;
        margin: 5px 5px 5px 5px;
        padding: 0px 5px 0px 5px;
        border-radius: 16px;
        border: solid 0px #f4d9e1;
        font-weight: normal;
        font-style: normal;
      }
      #workspaces button {
          padding: 0px 5px;
          border-radius: 16px;
          color: #a6adc8;
      }

      #workspaces button.active {
          color: #f4d9e1;
          background-color: transparent;
          border-radius: 16px;
      }

      #workspaces button:hover {
        background-color: #cdd6f4;
        color: black;
        border-radius: 16px;
      }

      #custom-date, #clock, #battery, #pulseaudio, #network, #custom-randwall, #custom-launcher {
        background: transparent;
        padding: 5px 5px 5px 5px;
        margin: 5px 5px 5px 5px;
        border-radius: 8px;
        border: solid 0px #f4d9e1;
      }

      #custom-date {
        color: #D3869B;
      }

      #custom-power {
        color: #24283b;
        background-color: #db4b4b;
        border-radius: 5px;
        margin-right: 10px;
        margin-top: 5px;
        margin-bottom: 5px;
        margin-left: 0px;
        padding: 5px 10px;
      }

      #tray {
          background: #45475a;
          margin: 5px 5px 5px 5px;
          border-radius: 16px;
          padding: 0px 5px;
          /*border-right: solid 1px #282738;*/
      }

      #clock {
          color: #cdd6f4;
          background-color: #45475a;
          border-radius: 0px 0px 0px 24px;
          padding-left: 13px;
          padding-right: 15px;
          margin-right: 0px;
          margin-left: 10px;
          margin-top: 0px;
          margin-bottom: 0px;
          font-weight: bold;
          /*border-left: solid 1px #282738;*/
      }

      #battery {
          color: #89b4fa;
      }

      #battery.charging {
          color: #a6e3a1;
      }

      #battery.warning:not(.charging) {
          background-color: #f7768e;
          color: #f38ba8;
          border-radius: 5px 5px 5px 5px;
      }

      #backlight {
          background-color: #24283b;
          color: #db4b4b;
          border-radius: 0px 0px 0px 0px;
          margin: 5px;
          margin-left: 0px;
          margin-right: 0px;
          padding: 0px 0px;
      }

      #network {
          color: #f4d9e1;
          border-radius: 8px;
          margin-right: 5px;
      }

      #pulseaudio {
          color: #f4d9e1;
          border-radius: 8px;
          margin-left: 0px;
      }

      #pulseaudio.muted {
          background: transparent;
          color: #928374;
          border-radius: 8px;
          margin-left: 0px;
      }

      #custom-randwall {
          color: #f4d9e1;
          border-radius: 8px;
          margin-right: 0px;
      }

      #custom-launcher {
          color: #e5809e;
          background-color: #45475a;
          border-radius: 0px 24px 0px 0px;
          margin: 0px 0px 0px 0px;
          padding: 0 20px 0 13px;
          /*border-right: solid 1px #282738;*/
          font-size: 20px;
      }

      #custom-launcher button:hover {
          background-color: #FB4934;
          color: transparent;
          border-radius: 8px;
          margin-right: -5px;
          margin-left: 10px;
      }

      #custom-playerctl {
        background: #45475a;
        padding-left: 15px;
        padding-right: 14px;
        border-radius: 16px;
        /*border-left: solid 1px #282738;*/
        /*border-right: solid 1px #282738;*/
        margin-top: 5px;
        margin-bottom: 5px;
        margin-left: 0px;
        font-weight: normal;
        font-style: normal;
        font-size: 16px;
      }

      #custom-playerlabel {
          background: transparent;
          padding-left: 10px;
          padding-right: 15px;
          border-radius: 16px;
          /*border-left: solid 1px #282738;*/
          /*border-right: solid 1px #282738;*/
          margin-top: 5px;
          margin-bottom: 5px;
          font-weight: normal;
          font-style: normal;
      }

      #window {
          background: #45475a;
          padding-left: 15px;
          padding-right: 15px;
          border-radius: 16px;
          /*border-left: solid 1px #282738;*/
          /*border-right: solid 1px #282738;*/
          margin-top: 5px;
          margin-bottom: 5px;
          font-weight: normal;
          font-style: normal;
      }

      #custom-wf-recorder {
          padding: 0 20px;
          color: #e5809e;
          background-color: #1E1E2E;
      }

      #cpu {
          background-color: #45475a;
          /*color: #FABD2D;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #memory {
          background-color: #45475a;
          /*color: #83A598;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #disk {
          background-color: #45475a;
          /*color: #8EC07C;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #custom-hyprpicker {
          background-color: #45475a;
          /*color: #8EC07C;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 11px 0px 9px;
          font-weight: bold;
      }
    '';
    settings = {
      mainBar = {
        layer = "top";
        position = "top";
        height = 50;

        output = config.monorepo.vars.monitors;

        modules-left = [ "hyprland/workspaces" ];
        modules-center = [ "hyprland/window" ];
        modules-right = [ "battery" "clock" ];

        battery = {
          format = "{icon}  {capacity}%";
          format-icons = ["" "" "" "" "" ];
        };

        clock = {
          format = "⏰ {:%a %d, %b %H:%M}";
        };
      };
    };
  };
}

6.25.16. Wofi

This is a run launcher for wayland. I also use it for my powermenu.

{ lib, config, ... }:
{
  programs.wofi = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    settings = {
      location = "bottom-right";
      allow_markup = true;
      show = "drun";
      width = 750;
      height = 400;
      always_parse_args = true;
      show_all = false;
      term = "kitty";
      hide_scroll = true;
      print_command = true;
      insensitive = true;
      prompt = "Run what, Commander?";
      columns = 2;
    };

    style = ''
      @define-color rosewater  #f5e0dc;
      @define-color rosewater-rgb  rgb(245, 224, 220);
      @define-color flamingo  #f2cdcd;
      @define-color flamingo-rgb  rgb(242, 205, 205);
      @define-color pink  #f5c2e7;
      @define-color pink-rgb  rgb(245, 194, 231);
      @define-color mauve  #cba6f7;
      @define-color mauve-rgb  rgb(203, 166, 247);
      @define-color red  #f38ba8;
      @define-color red-rgb  rgb(243, 139, 168);
      @define-color maroon  #eba0ac;
      @define-color maroon-rgb  rgb(235, 160, 172);
      @define-color peach  #fab387;
      @define-color peach-rgb  rgb(250, 179, 135);
      @define-color yellow  #f9e2af;
      @define-color yellow-rgb  rgb(249, 226, 175);
      @define-color green  #a6e3a1;
      @define-color green-rgb  rgb(166, 227, 161);
      @define-color teal  #94e2d5;
      @define-color teal-rgb  rgb(148, 226, 213);
      @define-color sky  #89dceb;
      @define-color sky-rgb  rgb(137, 220, 235);
      @define-color sapphire  #74c7ec;
      @define-color sapphire-rgb  rgb(116, 199, 236);
      @define-color blue  #89b4fa;
      @define-color blue-rgb  rgb(137, 180, 250);
      @define-color lavender  #b4befe;
      @define-color lavender-rgb  rgb(180, 190, 254);
      @define-color text  #cdd6f4;
      @define-color text-rgb  rgb(205, 214, 244);
      @define-color subtext1  #bac2de;
      @define-color subtext1-rgb  rgb(186, 194, 222);
      @define-color subtext0  #a6adc8;
      @define-color subtext0-rgb  rgb(166, 173, 200);
      @define-color overlay2  #9399b2;
      @define-color overlay2-rgb  rgb(147, 153, 178);
      @define-color overlay1  #7f849c;
      @define-color overlay1-rgb  rgb(127, 132, 156);
      @define-color overlay0  #6c7086;
      @define-color overlay0-rgb  rgb(108, 112, 134);
      @define-color surface2  #585b70;
      @define-color surface2-rgb  rgb(88, 91, 112);
      @define-color surface1  #45475a;
      @define-color surface1-rgb  rgb(69, 71, 90);
      @define-color surface0  #313244;
      @define-color surface0-rgb  rgb(49, 50, 68);
      @define-color base  #1e1e2e;
      @define-color base-rgb  rgb(30, 30, 46);
      @define-color mantle  #181825;
      @define-color mantle-rgb  rgb(24, 24, 37);
      @define-color crust  #11111b;
      @define-color crust-rgb  rgb(17, 17, 27);

      * {
        font-family: 'Iosevka Nerd Font', monospace;
        font-size: 14px;
      }

      /* Window */
      window {
        margin: 0px;
        padding: 10px;
        border: 0.16em solid @lavender;
        border-radius: 0.1em;
        background-color: @base;
        animation: slideIn 0.5s ease-in-out both;
      }

      /* Slide In */
      @keyframes slideIn {
        0% {
           opacity: 0;
        }

        100% {
           opacity: 1;
        }
      }

      /* Inner Box */
      #inner-box {
        margin: 5px;
        padding: 10px;
        border: none;
        background-color: @base;
        animation: fadeIn 0.5s ease-in-out both;
      }

      /* Fade In */
      @keyframes fadeIn {
        0% {
           opacity: 0;
        }

        100% {
           opacity: 1;
        }
      }

      /* Outer Box */
      #outer-box {
        margin: 5px;
        padding: 10px;
        border: none;
        background-color: @base;
      }

      /* Scroll */
      #scroll {
        margin: 0px;
        padding: 10px;
        border: none;
        background-color: @base;
      }

      /* Input */
      #input {
        margin: 5px 20px;
        padding: 10px;
        border: none;
        border-radius: 0.1em;
        color: @text;
        background-color: @base;
        animation: fadeIn 0.5s ease-in-out both;
      }

      #input image {
          border: none;
          color: @red;
      }

      #input * {
        outline: 4px solid @red!important;
      }

      /* Text */
      #text {
        margin: 5px;
        border: none;
        color: @text;
        animation: fadeIn 0.5s ease-in-out both;
      }

      #entry {
        background-color: @base;
      }

      #entry arrow {
        border: none;
        color: @lavender;
      }

      /* Selected Entry */
      #entry:selected {
        border: 0.11em solid @lavender;
      }

      #entry:selected #text {
        color: @mauve;
      }

      #entry:drop(active) {
        background-color: @lavender!important;
      }
    '';
  };
}

6.25.17. yt-dlp

A classic program that allows you to download from youtube. Also has integrations with mpv.

{ lib, config, ... }:
{
  programs.yt-dlp = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    settings = {
      embed-thumbnail = true;
      embed-subs = true;
      sub-langs = "all";
      downloader = "aria2c";
      downloader-args = "aria2c:'-c -x8 -s8 -k1M'";
    };
  };
}

6.25.18. Zsh

My zsh config has some useful aliases that one should read through. Otherwise it is pretty standard.

{ lib, config, pkgs, systemHostName, ... }:
{
  programs.zsh = {
    enable = true;
    initContent = ''
    umask 0022
    export EXTRA_CCFLAGS="-I/usr/include"
    source ${pkgs.zsh-vi-mode}/share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
    export QT_QPA_PLATFORM="wayland"
    export OLLAMA_MODEL="qwen3:14b"
    '';

    localVariables = {
      EDITOR = "emacsclient --create-frame --alternate-editor=vim";
      INPUT_METHOD = "fcitx";
      QT_IM_MODULE = "fcitx";
      GTK_IM_MODULE = "fcitx";
      XMODIFIERS = "@im=fcitx";
      XIM_SERVERS = "fcitx";
      WXSUPPRESS_SIZER_FLAGS_CHECK = "1";
    };

    shellAliases = {
      c = "clear";
      g = "git";
      v = "vim";
      py = "python3";
      rb = "sudo nixos-rebuild switch --flake $HOME/monorepo/nix#${systemHostName}";
      nfu = "cd ~/monorepo/nix && git add . && git commit -m \"new flake lock\" &&  nix flake update";
      usync =  "rsync -azvP --chmod=\"Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r\" ~/website_html/ root@${config.monorepo.vars.remoteHost}:/var/www/ret2pop-website/";
      usite
      = "cd ~/src/publish-org-roam-ui && bash local.sh && rm -rf ~/website_html/graph_view; cp -r ~/src/publish-org-roam-ui/out ~/website_html/graph_view && rsync -azvP --chmod=\"Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r\" ~/website_html/ root@${config.monorepo.vars.remoteHost}:/var/www/ret2pop-website/";
      sai = "eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && ssh-add -l";
      i3 = "exec ${pkgs.i3-gaps}/bin/i3";
    };
    loginExtra = ''
      if [[ "$(tty)" = "/dev/tty1" ]]; then
          exec Hyprland
      fi
    '';
  };
}

6.25.19. Pantalaimon

This is used with ement as a proxy in order to connect to a remote matrix server while having encryption.

{ lib, config, ... }:
{
  services.pantalaimon = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    settings = {
      Default = {
        LogLevel = "Debug";
        SSL = true;
      };
      local-matrix = {
        Homeserver = "https://social.nullring.xyz";
        ListenAddress = "127.0.0.1";
        ListenPort = "8008";
      };
    };
  };
}

6.25.20. User

This configuration is the backbone configuration for the default user. It specifies some generally useful packages and something every home should have, as well as some dependencies for these configurations.

{ lib, config, pkgs, ... }:
{
  home = {
    activation.startup-files = lib.hm.dag.entryAfter [ "installPackages" ] ''
    if [ ! -d "/home/${config.monorepo.vars.userName}/email/ret2pop/" ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/email/ret2pop/
    fi
    if [ ! -d "/home/${config.monorepo.vars.userName}/music" ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/music
    fi
    if [ ! -d /home/${config.monorepo.vars.userName}/org ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/org
    fi
    if [ ! -d /home/${config.monorepo.vars.userName}/src ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/src
    fi
    touch /home/${config.monorepo.vars.userName}/org/agenda.org
    touch /home/${config.monorepo.vars.userName}/org/notes.org
    '';

    enableNixpkgsReleaseCheck = false;
    username = config.monorepo.vars.userName;
    homeDirectory = "/home/${config.monorepo.vars.userName}";
    stateVersion = "24.11";

    packages = with pkgs; (if config.monorepo.profiles.graphics.enable then [
      # wikipedia
      # kiwix kiwix-tools
      mupdf
      zathura

      fzf
      # passwords
      age sops

      # formatting
      ghostscript texliveFull pandoc

      # Emacs Deps
      graphviz jq

      # Apps
      # octaveFull
      vesktop grim swww vim telegram-desktop qwen-code

      # Sound/media
      pavucontrol alsa-utils imagemagick ffmpeg helvum

      # Net
      curl rsync git iamb

      # Tor
      torsocks tor-browser

      # fonts
      nerd-fonts.iosevka noto-fonts noto-fonts-cjk-sans noto-fonts-emoji fira-code font-awesome_6
      (aspellWithDicts
        (dicts: with dicts; [ en en-computers en-science ]))

      # Misc.
      pinentry
      x11_ssh_askpass
      xdg-utils
      acpilight
      pfetch
      libnotify
      htop
      (writeShellScriptBin "remote-build"
        ''
#!/bin/bash
nixos-rebuild --sudo --ask-sudo-password --target-host "$1" switch --flake $HOME/monorepo/nix#spontaneity
''
      )
      (writeShellScriptBin "install-vps"
        ''
#!/bin/bash
nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config $HOME/monorepo/nix/systems/spontaneity/hardware-configuration.nix --flake $HOME/monorepo/nix#spontaneity --target-host "$1"
        '')
    ] else [
      pfetch

      # net
      curl
      torsocks
      rsync
    ]);
  };

  services = {
    gpg-agent = {
      pinentry.package = pkgs.pinentry-emacs;
      enable = true;
      extraConfig = ''
      allow-emacs-pinentry
      allow-loopback-pinentry
    '';
    };
  };

  programs.bash.enable = true;

  gtk = {
    enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
    theme = null;
    iconTheme = null;
  };

  fonts.fontconfig.enable = true;
}

7. Systems

7.1. Home

This module dynamically imports the correct corresponding home.nix at the path.

{ config, sops-nix, ... }:
{
  home-manager = {

    sharedModules = [
      sops-nix.homeManagerModules.sops
    ];
    useGlobalPkgs = true;
    useUserPackages = true;
    users."${config.monorepo.vars.userName}" = import (./. + "/${config.networking.hostName}/home.nix");
  };
}

7.2. Includes

These are the common includes for each of my systems. This ensures that we don't have to duplicate includes every time we want to add a new system.

{ config, lib, ... }:
{
  imports = [
    ./home.nix
    ../modules/default.nix
  ];
}

7.3. Continuity

This is pretty understandable, if you understand all the above.

{ ... }:
{
  imports = [
    ../../disko/drive-simple.nix
    ../includes.nix
  ];
  config = {
    # drive to install to
    monorepo.vars.device = "/dev/sda";
  };
}

7.3.1. Home

Each system has a corresponding home configuration in order to set monorepo home options.

{ lib, config, pkgs, ... }:
{
  imports = [
    ../../modules/home/default.nix
  ];
  config.monorepo.profiles.workstation.enable = false;
}

7.4. Affinity

This is my configuration for my workstation. It runs ollama, as well as several other useful services.

{ config, lib, home-manager, ... }:
{
  imports = [
    ../includes.nix
    ../../disko/drive-simple.nix
  ];
  config = {
    monorepo = {
      vars.device = "/dev/nvme0n1";
      profiles = {
        server.enable = false;
        cuda.enable = true;
        workstation.enable = true;
      };
    };
  };
}

7.4.1. Home

{ lib, config, pkgs, ... }:
{
  imports = [
    ../../modules/home/default.nix
  ];
  config.monorepo = {
    profiles.cuda.enable = true;
  };
}

7.5. Spontaneity

Spontaneity is my VPS instance.

{ config, lib, ... }:
{
  imports = [
    ../includes.nix
    # nixos-anywhere generates this file
    ./hardware-configuration.nix
    ../../disko/drive-bios.nix
  ];
  config = {
    monorepo = {
      vars.device = "/dev/vda";
      profiles = {
        server.enable = true;
        ttyonly.enable = true;
        grub.enable = true;
      };
    };

    boot.loader.grub.device = "nodev";
    networking = {
      firewall.allowedTCPPorts = [
        80
        443
        465
        993
        8448
        6697
        6667
      ];
      domains = {
        enable = true;
        baseDomains = {
          "${config.monorepo.vars.remoteHost}" = {
            a.data = "66.42.84.130";
            aaaa.data = "2001:19f0:5401:10d0:5400:5ff:fe4a:7794";
          };
          "nullring.xyz" = {
            a.data = "66.42.84.130";
            aaaa.data = "2001:19f0:5401:10d0:5400:5ff:fe4a:7794";
          };
        };
        subDomains = {
          "${config.monorepo.vars.remoteHost}" = {};
          "matrix.${config.monorepo.vars.remoteHost}" = {};
          "www.${config.monorepo.vars.remoteHost}" = {};
          "mail.${config.monorepo.vars.remoteHost}" = {};

          "nullring.xyz" = {};
          "git.nullring.xyz" = {};
          "matrix.nullring.xyz" = {};
          "talk.nullring.xyz" = {};
          "mail.nullring.xyz" = {};
          "ret2pop.nullring.xyz" = {};
        };
      };
    };
  };
}

7.5.1. Home

{ lib, config, pkgs, ... }:
{
  imports = [
    ../../modules/home/default.nix
  ];
  config.monorepo.profiles.enable = false;
}

7.6. Installer

My installer installs my systems almost completely without interaction. You can also make them install the exact version of the system that you want it to by pinning the commits to make it always work in the exact same deterministic way.

7.6.1. Commit Hash Pinning

Modify this to pin the installer image hash to make the installer image always work deterministically.

{
  diskoCommitHash = "c8a0e78d86b12ea67be6ed0f7cae7f9bfabae75a";
  monorepoCommitHash = "64a1acc961466c845b2601c0d0e165b16eb73fe2";
  monorepoUrl = "https://github.com/ret2pop/monorepo";
}

7.6.2. ISO Default Profile

This contains the installation script I use to install my systems.

{ pkgs, config, lib, modulesPath, ... }:
let
  commits = import ./commits.nix;
in
{
  imports = [
    (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")
  ];

  networking = {
    networkmanager = {
      enable = true;
    };
    firewall = {
      allowedTCPPorts = [ 22 ];
      allowedUDPPorts = [ ];
    };
    wireless.enable = false;
  };
  services.openssh = {
    enable = true;
    ports = [ 22 ];
    settings = {
      PasswordAuthentication = false;
      AllowUsers = null;
      UseDns = true;
      PermitRootLogin = lib.mkForce "prohibit-password";
    };
  };

  users.extraUsers.root.password = "nixos";
  users.extraUsers.nixos.password = "nixos";
  users.users = {
    root.openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell"
    ];
    nixos = {
      packages = with pkgs; [
        git
        curl
        gum
        (writeShellScriptBin "nix_installer"
          ''
#!/usr/bin/env bash

set -euo pipefail

if [ "$(id -u)" -eq 0 ]; then
  echo "ERROR! $(basename "$0") should be run as a regular user"
  exit 1
fi

cd "$HOME"

ping -q -c1 google.com &>/dev/null && echo "online! Proceeding with the installation..." || nmtui

gum style --border normal --margin "1" --padding "1 2" "Choose a system to install or select `new` in order to create a new system."

SYSTEM="$(gum choose $(find "$HOME/monorepo/nix/systems" -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | grep -v -E 'installer'; printf "New"))"

if [[ "$SYSTEM" == "New" ]]; then
  gum style --border normal --margin "1" --padding "1 2" "Choose a system name"
  SYSTEM="$(gum input --placeholder "system name")"

  gum style --border normal --margin "1" --padding "1 2" "Select a drive file or create a new drive file."
  DRIVE="$(gum choose $(find "$HOME/monorepo/nix/disko" -mindepth 1 -maxdepth 1 -type f -printf "%f\n"; printf "New"))"

  if [[ "$DRIVE" == "New" ]]; then
    gum style --border normal --margin "1" --padding "1 2" "Choose a name to call your drive file."
    DRIVE="$(gum input --placeholder "drive file name (ex: partition_scheme.nix)")"
  fi
fi

if [ ! -d "$HOME/monorepo/" ]; then
  git clone ${commits.monorepoUrl}
  cd "$HOME/monorepo"
  git checkout "${commits.monorepoCommitHash}"
  cd "$HOME"
fi


if [ ! -d "$HOME/monorepo/nix/systems/$SYSTEM" ]; then
  mkdir -p "$HOME/monorepo/nix/systems/$SYSTEM"
  cp "$HOME/monorepo/nix/systems/continuity/home.nix" "$HOME/monorepo/nix/systems/$SYSTEM/home.nix"
  cat > "$HOME/monorepo/nix/systems/$SYSTEM/default.nix" <<EOF
{ ... }:
{
  imports = [
    ../includes.nix
    ../../disko/$DRIVE
  ];
  # CHANGEME
  config.monorepo.vars.drive = "/dev/sda";
}
EOF

  gum style --border normal --margin "1" --padding "1 2" "Edit the system default.nix with options."
  gum input --placeholder "Press Enter to continue" >/dev/null
  vim "$HOME/monorepo/nix/systems/$SYSTEM/default.nix"

  gum style --border normal --margin "1" --padding "1 2" "Edit the home default.nix with options."
  gum input --placeholder "Press Enter to continue" >/dev/null
  vim "$HOME/monorepo/nix/systems/$SYSTEM/home.nix"

  sed -i "/# add hostnames here/i \  \"$1\"" "$HOME/monorepo/nix/flake.nix"

  if [ ! -f "$HOME/monorepo/nix/disko/$DRIVE" ]; then
    cp "$HOME/monorepo/nix/disko/drive-simple.nix" "$HOME/monorepo/nix/disko/$DRIVE"
    gum style --border normal --margin "1" --padding "1 2" "Edit the drive file with your preferred partitioning scheme."
    gum input --placeholder "Press Enter to continue" >/dev/null
    vim "$HOME/monorepo/nix/disko/$DRIVE"
  fi
  cd "$HOME/monorepo" && git add . && cd "$HOME"
fi

nix --extra-experimental-features 'nix-command flakes' eval "$HOME/monorepo/nix#evalDisko.$SYSTEM" > "$HOME/drive.nix"

gum style --border normal --margin "1" --padding "1 2" "Formatting the drive is destructive!"
if gum confirm "Are you sure you want to continue?"; then
    echo "Proceeding..."
else
    echo "Aborting."
    exit 1
fi

sudo nix --experimental-features "nix-command flakes" run "github:nix-community/disko/${commits.diskoCommitHash}" -- --mode destroy,format,mount "$HOME/drive.nix"

cd /mnt
sudo nixos-install --flake "$HOME/monorepo/nix#$SYSTEM"

target_user="$(ls /mnt/home | head -n1)"
if [ -z "$target_user" ]; then
    echo "No user directories found in /mnt/home"
    exit 1
fi
sudo cp -r "$HOME/monorepo" "/mnt/home/$target_user/"

echo "rebooting..."; sleep 3; reboot
'')
      ];
    };
  };

  systemd = {
    services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
    targets = {
      sleep.enable = false;
      suspend.enable = false;
      hibernate.enable = false;
      hybrid-sleep.enable = false;
    };
  };
}

8. Add System Script

Here is a script to add a new system automatically:

#!/usr/bin/env bash
sed -i "/# add hostnames here/i \  \"$1\"" "$HOME/monorepo/nix/flake.nix"
sed -i "/# add hostnames here/i \  \"$1\"" "$HOME/monorepo/config/nix.org"

mkdir -p "$HOME/monorepo/nix/systems/$1"

cat > "$HOME/monorepo/nix/systems/$1/default.nix" <<EOF
{ ... }:
{
  imports = [
    ../includes.nix
    ../../disko/drive-simple.nix
  ];
  # CHANGEME
  config.monorepo.vars.drive = "/dev/sda";
}
EOF

cp "$HOME/monorepo/nix/systems/continuity/home.nix" "$HOME/monorepo/nix/systems/$1/home.nix"

note that one will have to add some files to this org file afterwards, but this is a fine short term solution.

Copyright © 2024 Preston Pan