infrastructure

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

configuration.nix (14138B)


      1 {
      2   config,
      3   pkgs,
      4   pkgs-unstable,
      5   lib,
      6   ...
      7 }:
      8 
      9 {
     10   imports = [
     11     ./hardware-configuration.nix
     12     ./home.nix
     13     ../../modules/wireguard-client.nix
     14     ../../modules/gitea-runner.nix
     15     ../../modules/mkv.nix
     16     ../../modules/ollama.nix
     17     ../../modules/paperless.nix
     18     ../../modules/syncthing.nix
     19   ];
     20 
     21   sops.defaultSopsFile = ../../secrets.yaml;
     22   sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
     23 
     24   sops.secrets.gaia_forgejo_access_token = { };
     25   sops.secrets.silas_at_silasbrack_dot_com_password = { owner = "silas"; };
     26   sops.secrets.silasbrack_at_gmail_dot_com_app_password = { owner = "silas"; };
     27   sops.templates."authinfo" = {
     28     content = "machine git.fnarglebeast.com/api/v1 login silas^forge password ${config.sops.placeholder.gaia_forgejo_access_token}\n";
     29     path = "/home/silas/.authinfo.gpg";
     30     owner = "silas";
     31   };
     32 
     33   nix.settings.experimental-features = [
     34     "nix-command"
     35     "flakes"
     36   ];
     37   nix.gc = {
     38     automatic = true;
     39     dates = "weekly";
     40     options = "--delete-older-than 30d";
     41   };
     42   nix.settings = {
     43     max-jobs = 2;
     44     cores = 4;
     45   };
     46 
     47   boot.loader.systemd-boot.enable = true;
     48   boot.loader.efi.canTouchEfiVariables = true;
     49 
     50   boot.kernelPackages = pkgs.linuxPackages_latest;
     51   boot.initrd.kernelModules = [ "amdgpu" ];
     52 
     53   nixpkgs.config.rocmSupport = true;
     54   hardware.graphics = {
     55     enable = true;
     56     enable32Bit = true;
     57   };
     58   hardware.graphics.extraPackages = [ pkgs.rocmPackages.clr ];
     59   hardware.enableRedistributableFirmware = true;
     60 
     61   networking.hostName = "gaia";
     62   networking.networkmanager.enable = true;
     63 
     64   time.timeZone = "Europe/Copenhagen";
     65   i18n.defaultLocale = "en_DK.UTF-8";
     66   i18n.extraLocaleSettings = {
     67     LC_ADDRESS = "en_US.UTF-8";
     68     LC_IDENTIFICATION = "en_US.UTF-8";
     69     LC_MEASUREMENT = "en_US.UTF-8";
     70     LC_MONETARY = "en_US.UTF-8";
     71     LC_NAME = "en_US.UTF-8";
     72     LC_NUMERIC = "en_US.UTF-8";
     73     LC_PAPER = "en_US.UTF-8";
     74     LC_TELEPHONE = "en_US.UTF-8";
     75     LC_TIME = "en_US.UTF-8";
     76   };
     77 
     78   services.displayManager.ly.enable = true;
     79   services.desktopManager.plasma6.enable = true;
     80   environment.etc."xdg/kwalletrc".text = ''
     81     [Wallet]
     82     Enabled=false
     83     First Use=false
     84   '';
     85 
     86   services.pulseaudio.enable = false;
     87   security.rtkit.enable = true;
     88   services.pipewire = {
     89     enable = true;
     90     alsa.enable = true;
     91     alsa.support32Bit = true;
     92     pulse.enable = true;
     93     jack.enable = true;
     94   };
     95 
     96   fonts = {
     97     enableDefaultPackages = true;
     98     packages = with pkgs; [
     99       jetbrains-mono
    100       nerd-fonts.jetbrains-mono
    101       nerd-fonts.iosevka
    102       # font-bitstream-type1
    103       ibm-plex
    104       merriweather
    105       libertinus
    106       paratype-pt-sans
    107     ];
    108     fontconfig = {
    109       enable = true;
    110       hinting.style = "slight";
    111       subpixel.rgba = "rgb";
    112       defaultFonts = {
    113         sansSerif = [ "IBM Plex Sans" ];
    114         serif = [ "Merriweather" ];
    115         monospace = [ "JetBrains Mono" ];
    116       };
    117       confPackages = [
    118         (pkgs.writeTextDir "etc/fonts/conf.d/99-math.conf" ''
    119           <?xml version="1.0"?>
    120           <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
    121           <fontconfig>
    122             <alias>
    123               <family>math</family>
    124               <prefer>
    125                 <family>Libertinus Math</family>
    126               </prefer>
    127             </alias>
    128           </fontconfig>
    129         '')
    130       ];
    131     };
    132   };
    133 
    134   environment.sessionVariables = {
    135     EDITOR = "vim";
    136     BROWSER = "firefox";
    137     TERM = "wezterm";
    138     SHELL = "bash";
    139     HISTIGNORE = "&:ls:exit:pwd:clear:tmux:bash:nvim";
    140     HISTCONTROL = "ignoreboth";
    141     HISTSIZE = "65535";
    142     HISTFILESIZE = "65535";
    143   };
    144 
    145   environment.systemPackages = with pkgs; [
    146     gnupg
    147     pinentry-emacs
    148     pinentry-tty
    149     universal-ctags
    150   ];
    151 
    152   nixpkgs.config.allowUnsupportedSystem = true;
    153   nixpkgs.config.allowUnfreePredicate =
    154     pkg:
    155     builtins.elem (lib.getName pkg) [
    156       "claude-code"
    157       "spotify"
    158     ];
    159   users.users.silas = {
    160     isNormalUser = true;
    161     description = "Silas Brack";
    162     extraGroups = [
    163       "networkmanager"
    164       "wheel"
    165       "render"
    166       "video"
    167       "audio"
    168       "jackaudio"
    169     ];
    170     openssh.authorizedKeys.keys = [
    171       "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdP3Rvuv/pjQ/7akONRmId3zx7RE5Wqz+0V6eHy+KlE silasbrack@gmail.com"
    172     ];
    173     packages = with pkgs; [
    174       # anki
    175       # blender
    176       # btop-rocm
    177       claude-code
    178       # discord
    179       # duckdb
    180       # rocmPackages.clr
    181       # rocmPackages.rocm-smi
    182       # rocmPackages.rocminfo
    183       # (pkgs.haskellPackages.ghcWithPackages (ps: [ ps.tidal ]))
    184       # pkgs.supercollider-with-sc3-plugins
    185       # pkgs.ghc
    186       # pkgs.jack2
    187       # (emacs.pkgs.withPackages (ep: [
    188       #   ep.magit
    189       #   ep.eat
    190       #   ep.inheritenv
    191       #   ep.emms
    192       #   ep.expand-region
    193       #   ep.hyperbole
    194       #   ep.projectile
    195       #   ep.tidal
    196       #   ep.htmlize
    197       #   ep.ox-pandoc
    198       #   ep.notmuch
    199       #   (ep.treesit-grammars.with-grammars (g: [
    200       #     g.tree-sitter-python
    201       #     g.tree-sitter-rust
    202       #     g.tree-sitter-nix
    203       #   ]))
    204       # ]))
    205       # entr
    206       fd
    207       # feh
    208       # ffmpeg
    209       firefox
    210       # foot
    211       fzf
    212       # gcc
    213       # gimp
    214       git
    215       # gnumake
    216       # hadolint
    217       # inkscape
    218       isync
    219       jq
    220       keepassxc
    221       # kitty
    222       # kiwix
    223       # lazygit
    224       ledger
    225       # localsend
    226       # mosh
    227       mpv
    228       msmtp
    229       # ncdu
    230       # nil
    231       # nixfmt-rfc-style
    232       notmuch
    233       # obs-studio
    234       # obsidian
    235       # pandoc
    236       # pass
    237       # pdftk
    238       # prettierd
    239       # rclone
    240       ripgrep
    241       # rsync
    242       # shellcheck
    243       # signal-desktop
    244       spotify
    245       # sqlite
    246       # streamlink
    247       # streamlink-twitch-gui-bin
    248       # sublime4
    249       transmission_4-qt
    250       wezterm
    251       # yt-dlp
    252       # zathura
    253       # zotero
    254     ];
    255   };
    256 
    257   programs.vim = {
    258     enable = true;
    259     defaultEditor = true;
    260     package = (pkgs.vim.override { }).customize {
    261       name = "vim";
    262       vimrcConfig.customRC = ''
    263         set backspace=indent,eol,start
    264 
    265         set showmatch
    266         set incsearch
    267         set hlsearch
    268         set ignorecase
    269         set smartcase
    270 
    271         set wildmenu
    272         set wildoptions=pum
    273 
    274         set hidden
    275 
    276         set autoindent
    277 
    278         set number
    279         set relativenumber
    280 
    281         set tabstop=4
    282         set shiftwidth=4
    283 
    284         set expandtab
    285         set showmatch
    286 
    287         filetype plugin indent on
    288         syntax on
    289 
    290         set shell=/run/current-system/sw/bin/bash
    291         set tags=./tags,tags
    292 
    293         nnoremap gb :ls<CR>:b<Space>
    294         nnoremap gs :vimgrep /\%1l/ `fd -t=f `<left>
    295         nnoremap gS :vimgrep // `fd -t=f`<C-left><C-left><C-left><right>
    296 
    297         nnoremap <nowait><silent> <C-l> :noh<CR>
    298 
    299         nnoremap [q :cprev<CR>
    300         nnoremap ]q :cnext<CR>
    301         nnoremap [Q :cfirst<CR>
    302         nnoremap ]Q :clast<CR>
    303       '';
    304     };
    305   };
    306 
    307   programs.bash = {
    308     interactiveShellInit = ''
    309       shopt -s histappend
    310       PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
    311 
    312       eval "$(fzf --bash)"
    313 
    314       kpc() {
    315         local db="''\${1:-$HOME/passwords/Passwords.kdbx}"
    316         local pw entry
    317         read -rs -p "DB password: " pw; echo
    318         entry=$(keepassxc-cli ls -f -R "$db" <<< "$pw" 2>/dev/null \
    319                 | grep -v '/$' | fzf) || { pw=; return; }
    320         keepassxc-cli clip "$db" "$entry" <<< "$pw"
    321         pw=
    322       }
    323 
    324       loadenv() {
    325         set -a;
    326         source "''\${1:-.env}";
    327         set +a;
    328       }
    329     '';
    330   };
    331 
    332   programs.git = {
    333     enable = true;
    334     config = {
    335       user = {
    336         email = "silasbrack@gmail.com";
    337         name = "Silas Brack";
    338       };
    339       init.defaultBranch = "main";
    340       merge.conflictStyle = "zdiff3";
    341       "gitea.git.fnarglebeast.com/api/v1".user = "silas";
    342     };
    343   };
    344 
    345   programs.firefox = {
    346     enable = true;
    347     package = (pkgs.wrapFirefox (pkgs.firefox-unwrapped.override { pipewireSupport = true; }) { });
    348     preferences = {
    349       "privacy.resistFingerprinting" = true;
    350       "browser.urlbar.quicksuggest.online.enabled" = false;
    351       "browser.urlbar.suggest.quicksuggest.sponsored" = false;
    352       "browser.ml.chat.enabled" = false;
    353       "browser.newtabpage.activity-stream.showSponsored" = false;
    354       "browser.newtabpage.activity-stream.showSponsoredCheckboxes" = false;
    355       "browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
    356 
    357       # Disable password manager
    358       "signon.rememberSignons" = false;
    359       "signon.autofillForms" = false;
    360       "signon.generation.enabled" = false;
    361       "signon.management.page.breach-alerts.enabled" = false;
    362       "signon.firefoxRelay.feature" = false;
    363 
    364       # Don't let websites override my font choices
    365       "browser.display.use_document_fonts" = 0;
    366     };
    367     policies = {
    368       SearchEngines = {
    369         Default = "Kagi";
    370 
    371         # Remove built-ins you don't want
    372         Remove = [
    373           "Google"
    374           "Bing"
    375           "eBay"
    376           "DuckDuckGo"
    377           "Perplexity"
    378         ];
    379 
    380         # Add custom engines
    381         Add = [
    382           {
    383             Name = "Kagi";
    384             URLTemplate = "https://kagi.com/search?q={searchTerms}";
    385             IconURL = "https://kagi.com/asset/de8b73c/kagi_assets/logos/search.svg";
    386             Alias = "k";
    387           }
    388         ];
    389       };
    390       DisableTelemetry = true;
    391       SearchSuggestEnabled = false;
    392       DontCheckDefaultBrowser = true;
    393     };
    394   };
    395 
    396   services.openssh.enable = true;
    397   programs.ssh.knownHosts = {
    398     "git.fnarglebeast.com".publicKey =
    399       "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOKImx9KgmG+/ggpuS2z/hXkWu3TgT/xK9fI18tPOI1";
    400     "github.com".publicKey =
    401       "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
    402   };
    403 
    404   services.local.wireguard-client = {
    405     enable = true;
    406     address = "10.100.0.4/24";
    407     privateKeySecretName = "gaia_wireguard_private_key";
    408     routeAllTraffic = true;
    409   };
    410 
    411   services.local.ollama = {
    412     enable = true;
    413     rocmOverrideGfx = "11.0.1";
    414     visibleDevices = "GPU-198836ed61e1b1cc";
    415   };
    416 
    417   services.local.paperless = {
    418     enable = true;
    419     dateOrder = "YMD";
    420     ocrLanguages = "deu+eng";
    421   };
    422 
    423   services.local.syncthing = {
    424     enable = true;
    425     user = "silas";
    426     dataDir = "/home/silas/.syncthing";
    427     configDir = "/home/silas/.config/syncthing";
    428     devices = {
    429       "Lolo's Macbook Pro" = {
    430         id = "AODRMP6-CEUBLIG-QFOJBXH-2S5DZ43-F2OSK7I-DDLXY3A-OSGZZEY-GKG4EQF";
    431       };
    432       "Pixel 6a" = {
    433         id = "W3J66VB-KZYFQXI-UKL5XNO-D6W4KSA-2YAB7AZ-2BJ2BXA-T5ID4YA-NR22FQD";
    434       };
    435       "Work Macbook Pro" = {
    436         id = "W3RN76W-PDTHRF7-QYT6LAV-ML5OR5D-IH4MTHC-IQRJT6C-R7JGYYS-ISMEKQ6";
    437       };
    438     };
    439     folders = {
    440       "Notes" = {
    441         id = "7mruq-r5ufp";
    442         path = "/home/silas/notes";
    443         devices = [
    444           "Lolo's Macbook Pro"
    445           "Pixel 6a"
    446           "Work Macbook Pro"
    447         ];
    448       };
    449       "Textbooks" = {
    450         id = "z7wzr-eolsr";
    451         path = "/home/silas/docs/textbooks/";
    452         devices = [
    453           "Lolo's Macbook Pro"
    454           "Pixel 6a"
    455           "Work Macbook Pro"
    456         ];
    457       };
    458       "Test" = {
    459         id = "tkc8u-s54c3";
    460         path = "~/test";
    461         devices = [
    462           "Lolo's Macbook Pro"
    463           "Work Macbook Pro"
    464         ];
    465       };
    466       "Zotero" = {
    467         id = "7xkgb-tuqgw";
    468         path = "/home/silas/Zotero/storage";
    469         devices = [ "Lolo's Macbook Pro" ];
    470       };
    471       "Passwords" = {
    472         id = "dntxj-ku4il";
    473         path = "/home/silas/passwords";
    474         devices = [
    475           "Lolo's Macbook Pro"
    476           "Pixel 6a"
    477           "Work Macbook Pro"
    478         ];
    479       };
    480     };
    481   };
    482 
    483   services.postgresql = {
    484     enable = true;
    485     package = pkgs.postgresql_17;
    486     extensions = ps: with ps; [ pgvector ];
    487     ensureDatabases = [
    488       "paperless"
    489       "daily_tracker_dev"
    490     ];
    491     ensureUsers = [
    492       {
    493         name = "paperless";
    494         ensureDBOwnership = true;
    495       }
    496     ];
    497     authentication = pkgs.lib.mkOverride 10 ''
    498       #TYPE  DATABASE  USER                 AUTH-METHOD  OPTIONAL_IDENT_MAP
    499       # local  all       all                  peer         map=superuser_map
    500       local  all       all                  trust
    501       #TYPE  DATABASE  USER  ADDRESS        AUTH-METHOD
    502       host   all       all   127.0.0.1/32   trust
    503       host   all       all   ::1/128        trust
    504     '';
    505     identMap = ''
    506       # MAPNAME       SYSTEM-USERNAME   PG-USERNAME
    507       superuser_map   root              postgres
    508       superuser_map   postgres          postgres
    509       superuser_map   /^(.*)$           \1
    510     '';
    511   };
    512 
    513   services.local.mkv.volume = {
    514     enable = true;
    515     listenAddress = "10.100.0.4";
    516     path = "/var/lib/mkv/volume";
    517   };
    518 
    519   services.local.gitea-runner = {
    520     enable = true;
    521     name = "silas-desktop";
    522     tokenSecretName = "gaia_forgejo_runner_token";
    523     sshKeySecretName = "gaia_gitea_runner_ssh_key";
    524     knownHosts = [
    525       "46.62.150.48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOKImx9KgmG+/ggpuS2z/hXkWu3TgT/xK9fI18tPOI1"
    526       "git.fnarglebeast.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOKImx9KgmG+/ggpuS2z/hXkWu3TgT/xK9fI18tPOI1"
    527       "10.100.0.7 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOKImx9KgmG+/ggpuS2z/hXkWu3TgT/xK9fI18tPOI1"
    528       "188.166.127.72 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSAe7jj+yZ4iED+6u8oPX+UqEKzcZriLEXAVbjt3Cqo"
    529       "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"
    530     ];
    531   };
    532 
    533   # This value determines the NixOS release from which the default
    534   # settings for stateful data, like file locations and database versions
    535   # on your system were taken. It‘s perfectly fine and recommended to leave
    536   # this value at the release version of the first install of this system.
    537   # Before changing this value read the documentation for this option
    538   # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
    539   system.stateVersion = "23.11"; # Did you read the comment?
    540 
    541   virtualisation.containers.enable = true;
    542   virtualisation.podman = {
    543     enable = true;
    544     dockerCompat = true;
    545     defaultNetwork.settings.dns_enabled = true;
    546   };
    547   users.extraGroups.podman.members = [ "silas" ];
    548 }