Nixos Config

Table of Contents

For now this is the way I'm configuring nixos. There is no flakes here, just a configuration.nix and a bunch of other stuff

1. Prefix

The nixos config is going to consist of a bunch of "imports" which are just a bunch of configs in the imports part of the main configuration. Then we can put each part of said config on its own source block This does require a bit of a prefix, that lets us access packages, existing configuration and library functions

{ config, lib, pkgs, ... }:
let
  sources = import ./nix/sources.nix;
  nur = import sources.NUR { inherit pkgs; };
  nurModules = import sources.NUR { };
in
{
  imports = [
    <<nixos-config>>
  ];
}

2. Configuration

2.1. Hardware

Normal nixos installation comes with a hardware-configuration file. we are not going to add the contents of that file here ourself, but instead add it as an external module. This is the only place where we'll do this

./hardware-configuration.nix

Also i want to have a full bluetooth experience

{
  hardware.bluetooth = {
    enable = true;
    package = pkgs.bluez;
  };
}

2.2. personal stuff

First, some personal stuff, so that I can tel people my computer is mine

{
  options.mainUser = with lib; mkOption {
    type = types.str;
    default = builtins.getEnv "USER";
  };
}

and then the actual info:

{
  mainUser = "erik";
  networking.hostName = "RACEMONSTER";
  time.timeZone = "Europe/Amsterdam";
}

2.3. Main user config

This sets up a (secret) default password for the main user and also sets some default groups

{
  users.mutableUsers = false;
  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.${config.mainUser} = {
    initialHashedPassword = "$6$XTH/sALyqg$G.bMWemErh4KGCAjUfT16DL96QMn/4NTmxlw6Z26wUVJn.tagQG.Fzmrz7uPkdiWZbBBFWP36.YA4hw9AcL8Q1";
    isNormalUser = true;
    extraGroups = [ "video" "wheel" "NetworkManager" ]; # Enable ‘sudo’ for the user.
    # shell = pkgs.nushell;
  };
}

Furthermore, I want to have some prefabs available in my $PATH if I make them

{
  environment.shellInit =
    ''
     if [ -h /etc/nixos/nix-prefabs/result ]; then
      export PATH=$PATH:/etc/nixos/nix-prefabs/result/bin
     fi
    '';
}

2.4. Init system

nixos is started with systemd-boot, since we don't run any other distros

{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
}

2.5. nixpkgs setup

not much info here right now. emacs itself now refers to emacsng

{
  nix.package = pkgs.lix;
  programs.nix-ld = {
    enable = true;
    # use all the libraries that AppImage uses to load an image
    libraries = with pkgs; [fuse] ++ (with appimageTools.defaultFhsEnvArgs; multiPkgs pkgs ++ targetPkgs pkgs);
  };
  nixpkgs.config.allowUnfree = true;
  nixpkgs.overlays = [
    (final: prev: {
      emacs = (import sources.emacs-ng).outputs.packages."x86_64-linux".default;
      emacsWithPackages = final.emacs.pkgs.withPackages;
      inherit (nur.repos) instantos;
    })
  ];
}

2.5.1. cachix

Cachix and other substitute servers allow you to not have to compile things as much as you are supposed to We will create a small module for cachix before we put in the rest declaratively

{
  options.nix.cacheAttrs = with lib; mkOption {
    type = with types; attrsOf str;
    default = {};

  };
  config = with lib; {
    nix.settings.substituters = builtins.attrNames config.nix.cacheAttrs;
    nix.settings.trusted-public-keys = builtins.attrValues config.nix.cacheAttrs;
  };
}

With the config in hand, we can now quickly and easily declare our substitute servers

{
  nix.cacheAttrs = {
    "https://crazazy.cachix.org" = "crazazy.cachix.org-1:3KaIHK26pkvd5palJH5A4Re1Hn2+GDV+aXYnftMYAm4=";
    "https://emacsng.cachix.org" = "emacsng.cachix.org-1:i7wOr4YpdRpWWtShI8bT6V7lOTnPeI7Ho6HaZegFWMI=";
    # "https://ethancedwards8.cachix.org" = "ethancedwards8.cachix.org-1:YMasjqyFnDreRQ9GXmnPIshT3tYyFHE2lUiNhbyIxOc=";
    "https://nix-community.cachix.org" = "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
    # "https://nrdxp.cachix.org" = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4=";
    # "https://rycee.cachix.org" = "rycee.cachix.org-1:TiiXyeSk0iRlzlys4c7HiXLkP3idRf20oQ/roEUAh/A=";
    # "https://cache.iog.io" = "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=";
  };
}

2.6. udev binds

I have a bindmount system so that I can easily make binds to persistent directories from my home directory This should prevent clutter

2.6.1. The config

This part is quite advanced. It makes entries for filesystems and then makes a systemd service to re-assign generated temporary directories to the owner of the home folder

{
  options = with lib; {
    homeBinds = mkOption {
      type = with types; listOf str;
      default = [ ];
      description = "Bind mounts in your home folder";
    };
    persistRoot = mkOption {
      type = types.str;
      default = "/nix/persist";
    };
  };
  config = with lib; mkIf (config.homeBinds != [ ]) {
    fileSystems = genAttrs (map (loc: "/home/${config.mainUser}/${loc}") config.homeBinds)
      (loc: {
              device = "${config.persistRoot}${loc}";
              fsType = "none";
              options = [ "bind" ];
      });
    systemd.services.fix-home-perms = {
      wantedBy = [ "multi-user.target" ];
      after = map (loc: "${builtins.replaceStrings ["/"] ["-"] loc}.mount") config.homeBinds;
      serviceConfig.Type = "oneshot";
      script = "chown -R ${config.mainUser} /home/${config.mainUser}";
    };
  };
}

2.6.2. The binds

These are the binds themselves, they change frequently

{
  homeBinds = [
    ".config/keybase"
    ".local/share/keybase"
    ".ssh"
    "Desktop"
    "Documents/uni-docs"
    "Documents/IdeaProjects"
    "Documents/java-jars"
    "Documents/notes"
    "Music"
    "Videos"
  ];
}

2.7. Visual stuff (wayland)

After all, why shouldn't I try wayland? 😈

{
  programs.wayfire.enable = true;
  programs.wayfire.plugins = with pkgs.wayfirePlugins; [
    wcm
    wf-shell
    wayfire-plugins-extra
  ];
  sound.enable = true;
  fonts.packages = with pkgs; [
    noto-fonts
    noto-fonts-cjk
    noto-fonts-emoji
    liberation_ttf
    fira-code
    fira-code-symbols
    mplus-outline-fonts.githubRelease
    dina-font
    proggyfonts
  ];
  environment.systemPackages = with pkgs; [
    wofi waypipe 
  ];
}

2.8. Networking

Some default network settings for my laptop

{
  networking.networkmanager.enable = true; # Enables wireless support via NetworkManager
}

2.9. packages

2.9.1. Core packages

These are the normal packages that I use for core maintenance. I use a special hardened version of firefox that takes in some addons as well Hardened firefox source

{
  environment.systemPackages = let
    myFirefox = with pkgs; wrapFirefox librewolf-unwrapped {
      nixExtensions = builtins.filter lib.isDerivation (builtins.attrValues nur.repos.crazazy.firefox-addons);
      libName = "librewolf";
      extraPolicies = {
        CaptivePortal = false;
        DisableFirefoxStudies = true;
        DisablePocket = true;
        DisableTelemetry = true;
        DisableFirefoxAccounts = true;
        DontCheckDefaultBrowser = true;
        FirefoxHome = {
          Pocket = false;
          Snippets = false;
        };
        UserMessaging = {
          ExtensionRecommendations = false;
          SkipOnboarding = true;
        };
      };
      extraPrefs = ''
      // Show more ssl cert infos
      lockPref("security.identityblock.show_extended_validation", true);
      // Enable userchrome css
      lockPref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
      // Enable light dev tools
      lockPref("devtools.theme","light");
      // Misc other settings
      lockPref("extensions.autoDisableScopes", 0);
      lockPref("browser.uidensity", 1);
      lockPref("browser.search.openintab", true);
      lockPref("extensions.update.enabled", false);
      lockPref("identity.fxaccounts.enabled", false);
      lockPref("signon.rememberSignons", false);
      lockPref("signon.rememberSignons.visibilityToggle", false);
      lockPref("media.eme.enabled", true);
      lockPref("browser.eme.ui.enabled", true);
      lockPref("xpinstall.signatures.required",false);
      lockPref("browser.shell.checkDefaultBrowser", false );
    '';
    };
  in
    with pkgs; [
      bun
      # compcert
      curl
      # deno
      discord
      gitFull
      graalvm-ce
      libreoffice
      # krdc
      mpv
      # nur.repos.crazazy.seamonkey
      myFirefox
      unzip zip
      vim
      # vieb
      (wine.override { wineBuild = "wineWow"; })
    ];
  # persistent directory for my browser details
  homeBinds = [
    # ".mozilla/firefox"
    ".config/discord"
    ".wine"
  ];
}

2.9.2. Researchware

I am doing a research project and I need certain software to make that happen

{
  virtualisation.vswitch.enable = true;
  environment.systemPackages = with pkgs; [
    mininet
    # not universal for all pythons but it works for now
    (python3.withPackages (p: [(p.mininet-python.overrideAttrs (_: {
      postInstall = "cp $py/bin/mn $py/lib/python3.10/site-packages/mininet/__main__.py";
    }))]))
    opam
    bindfs
  ];
}

2.9.3. Steam

I like to play videogames sometimes, however steam also requires a little more special attention

{
  imports = [
    # nurModules.repos.crazazy.modules.private.steam-config
  ];
  programs.steam.enable = true;
  homeBinds = [
    ".local/share/Steam"
  ];
  environment.systemPackages = with pkgs; [
    steam
  ];
}

2.9.4. Emacs

Emacs needs to be integrated into the rest of the system. We are going to do that via a emacs daemon

{
  services.emacs = {
    # package = import ./emacs.nix;
    package = pkgs.emacs29-pgtk;
    defaultEditor = true;
    enable = true;
  };
  homeBinds = [
    ".config/emacs"
  ];
}

2.9.5. QEMU & frens

I also sometimes run qemu vms. The qemu's manager will be libvirtd, but not sure if I will even use that

{
  virtualisation.libvirtd.enable = true;
}

Author: Crazazy

Created: 2024-06-24 Mon 13:28

Validate