{ config, lib, pkgs, ... }: { ############################################################ ## Table of Contents ## ## 1) Nix Configs/Flakes ## ## 2) Boot Option ## ## 3) Filesystems ## ## 4) System Configuration ## ## 5) Networking ## ## |_5.1) Firewall ## ## |_5.2) Wireguard ## ## |_5.3) Pihole ## ## |_5.4) Nginx ## ## 6) Users and Sudo ## ## 7) General Packages ## ## 8) Services, Daemons, Scripts ## ## |_8.1) Docker & Containers ## ## |_8.2) Arrs suite ## ## 9) Customizations & variables ## ## |_9.1) Keyd keyboard settings ## ## |_9.2) Enviroment Variables ## ## ## ## ## ############################################################ ############################################################ ## ## ## 1: Inital Nix configuration ## ## ## ############################################################ imports = [ ./hardware-configuration.nix ]; ## Flakes and nix-command nix.settings = { experimental-features = [ "nix-command" "flakes" ]; trusted-users = [ "harley" ]; }; ## Allow unfree packages nixpkgs.config.allowUnfree = true; ## Overlay: stub broken python doc build (docutils bug in 26.11) nixpkgs.overlays = [ (final: prev: { python312 = prev.python312.overrideAttrs (old: { passthru = old.passthru // { doc = null; }; }); }) ]; ## Auto-upgrade system.autoUpgrade.enable = false; ############################################################ ## ## ## 2: Boot and Kernel ## ## ## ############################################################ ## btrfs support in the kernel and systemd boot stuff boot.loader.efi.canTouchEfiVariables = true; boot.loader.systemd-boot.enable = true; boot.initrd.supportedFilesystems = [ "btrfs"]; ## SSH and remote LUKS unlocking in initramfs boot.initrd.network.ssh.enable = true; boot.initrd.network.ssh.hostKeys = [ ./secrets/initrd/ssh_host_ed25519_key ]; boot.initrd.network.ssh.authorizedKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH4OAJ8iC7CQIcedVbU86xgoL4YkMWAG9bU6aj9v4Skb harley@utumno" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOnvzomqQoTWI7H2GpnqZO8tR7CwwwfUsylGu9IHWpAe u0_a392@localhost" ]; ## Initrd convenience: 'unlock' command boot.initrd.systemd.contents."/root/unlock".text = '' #!/bin/sh exec cryptsetup luksOpen /dev/disk/by-uuid/7d3b9cf3-0444-4cc9-80ba-e1401b783b6c nixroot ''; boot.initrd.systemd.contents."/root/.profile".text = '' export PATH=$PATH:/root ''; ## DHCP for initrd network (systemd stage 1) boot.initrd.systemd.network.enable = true; boot.initrd.systemd.network.networks."10-eno1" = { matchConfig.Name = "eno1"; networkConfig.DHCP = "ipv4"; }; ########################################################### ## ## ## 3: File systems ## ## ## ########################################################### ## Root, 512-GB, SSD-SATA, btrfs fileSystems."/".options = [ "compress=zstd" "noatime" "space_cache=v2" ]; ## 20TB Storage drive, HDD, btrfs #fileSystems."/storage/20TB" = { # device = "/dev/disk/by-uuid/ec172aa7-85f7-4375-a661-88fc66221620"; # fsType = "ext4"; # }; ## Post-boot unlock + mount 8TB LUKS data drive systemd.services.unlock-8tb = { description = "Unlock and mount 8TB storage"; after = [ "local-fs.target" ]; wants = [ "local-fs.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; script = '' /run/current-system/sw/bin/cryptsetup luksOpen \ --key-file /root/keyfiles/8tb.key \ /dev/disk/by-uuid/2bc4df99-677b-46d4-a1b8-38dd3c636a2b 8tb /run/current-system/sw/bin/mount /dev/mapper/8tb /storage/8TB /run/current-system/sw/bin/mount /storage/8TB/arrs-tmp/sabnzbd ''; }; ## 1TB storage drive, SSD-NVME, btrfs #fileSystems."/storage/ssd/" = { #device = " "; #fstype = "btrfs"; #}; ## automated Snapper snapshots for the root filesystem services.snapper = { configs."root" = { SUBVOLUME = "/"; ALLOW_USERS = [ "harley" ]; TIMELINE_CREATE = true; TIMELINE_CLEANUP = true; TIMELINE_MIN_AGE = "1800"; TIMELINE_LIMIT_HOURLY = "6"; TIMELINE_LIMIT_DAILY = "7"; TIMELINE_LIMIT_WEEKLY = "4"; TIMELINE_LIMIT_MONTHLY = "6"; TIMELINE_LIMIT_YEARLY = "0"; NUMBER_CLEANUP = true; NUMBER_LIMIT = "50"; }; }; ## snapper for recov services.snapper.configs."file7" = { SUBVOLUME = "/mnt/.recov"; ALLOW_USERS = [ "harley" ]; TIMELINE_CREATE = false; NUMBER_CLEANUP = false; }; ############################################################ ## ## ## 4: System Configuration ## ## ## ############################################################ ## Time/Locale time.timeZone = "America/New_York"; i18n.defaultLocale = "en_US.UTF-8"; ## Nvidia GPU services.xserver.videoDrivers = [ "nvidia" ]; hardware.graphics.enable = true; hardware.nvidia = { modesetting.enable = true; powerManagement.enable = true; open = false; nvidiaSettings = true; }; ## Greeter user for greetd login on tty6 LOOK INTO THIS, IDK WHAT IT IS users.users.greeter = { isSystemUser = true; group = "nogroup"; extraGroups = [ "video" "input" "seat" ]; description = "greetd login greeter"; }; ## greetd PAM service security.pam.services.greetd = {}; ## Display Manager (SDDM) and Plasma 6 services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; services.desktopManager.plasma6.enable = true; programs.kdeconnect.enable = true; ## Pipewire services.pipewire = { enable = true; pulse.enable = true; alsa.enable = true; alsa.support32Bit = true; }; # Xpadneo for xbox controller bluetooth hardware.xpadneo.enable = true; ############################################################ ## ## ## 5) Networking ## ## ## ############################################################ networking.hostName = "utumno"; networking.networkmanager.enable = true; # Don't block boot waiting for all network profiles to come online systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; hardware.bluetooth = { enable = true; powerOnBoot = true; settings.General.Experimental = true; }; ## ## ## 5.1 Firewall ## ## networking.firewall = { ## UDP ports and ranges allowedUDPPorts = [ 51820 51812 5113 ]; allowedUDPPortRanges = [ { from = 47884; to = 48010; } ]; ## TCP ports and ranges allowedTCPPorts = [ 22 3010 222 8084 443 80 8787 8180 7777 3180 47989 47990 47991 47992 48010 5113 8777 ]; # Enable IP forwarding (needed for Wireguard routing) enable = true; }; ## Enable Ip forwarding at the kernel level boot.kernel.sysctl."net.ipv4.ip_forward" = 1; ## SSHD services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "prohibit-password"; }; }; ## ## ## 5.2: Wireguard ## ## networking.wireguard.interfaces = { wg0 = { ips = [ "10.10.10.1/24" ]; listenPort = 51820; privateKeyFile = "/etc/nixos/secrets/wireguard/wg0-key.key"; # IP forwarding + NAT for wg0 clients to internet/LAN postSetup = '' ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE ''; postShutdown = '' ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE ''; peers = [ # Exos — routes remote subnets { publicKey = "8rO4j18cPAw6zv8b26PNXFHpEwxqjBq1r8yRmWNOMXY="; endpoint = "briggs.wiki:51820"; allowedIPs = [ "10.10.10.2/32" "10.0.0.0/24" "192.168.3.0/24" ]; } # Maroon / Roman Phone { publicKey = "Sih2qcJtmhdlSwxlaRont7ezwazo0FMyMxTjhWBtpjA="; allowedIPs = [ "192.168.3.1/32" ]; } # Palantir (Phone) { publicKey = "RUPXirLLTY1KeFIjfwKQtVg3ckj8sLz2QN/AiLZOmFw="; allowedIPs = [ "192.168.2.1/32" ]; } # Menegroth { publicKey = "DWhEqMQ7/RHkEuPtMrpuhQqnls7o/B6idSJxXJJy6ys="; allowedIPs = [ "192.168.2.2/32" ]; } # iPad { publicKey = "lqTK2qoaNJ+Md8RZT3TVxN+fAHllTwIG2znZKI3Rt2c="; allowedIPs = [ "192.168.2.3/32" ]; } ]; }; }; ## ## ## 5.3) Pi-hole DNS ## ## services.pihole-ftl = { enable = true; openFirewallDNS = true; ## Upstream DNS servers (Cloudflare and Quad9) settings = { dns = { upstreams = [ "1.1.1.1#53" "1.0.0.1#53" "9.9.9.9#53" ]; ## Listen on all interfaces listeningMode = "ALL"; ## Block ESNI, ICloud Private Relay, Firefox canary, etc. blocking.active = true; blocking.mode = "NULL"; ## Rate limiting rateLimit.count = 1000; rateLimit.interval = 60; ## Cache cache.size = 10000; cache.optimizer = 3600; ## DNSSEC dnssec = false; bogusPriv = true; domainNeeded = false; ## Local DNS records hosts = [ "10.0.1.49 jellyfin.wingard.pro" "10.0.1.49 speedtest.wingard.pro" ]; }; ## Web server on 8999, admin page at /admin/ webserver = { port = lib.mkForce "8999"; interface.boxed = "true"; interface.theme = "default-dark"; }; ## Privacy level 0 = full stats misc.privacylevel = 0; }; ## Blocklist: Steven Black's unified hosts lists = [ { url = "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"; description = "Steven Black's unified adlist"; } ]; }; ## Pi-hole web admin dashboard services.pihole-web.enable = true; ## ## ## 5.4: Nginx ## ## services.nginx = { enable = true; recommendedProxySettings = true; virtualHosts = { "jellyfin.wingard.pro" = { enableACME = false; addSSL = true; sslCertificate = "/etc/letsencrypt/live/jellyfin.wingard.pro/fullchain.pem"; sslCertificateKey = "/etc/letsencrypt/live/jellyfin.wingard.pro/privkey.pem"; locations."/" = { proxyPass = "http://127.0.0.1:8096"; proxyWebsockets = true; }; }; "speedtest.wingard.pro" = { enableACME = false; addSSL = true; sslCertificate = "/etc/letsencrypt/live/speedtest.wingard.pro/fullchain.pem"; sslCertificateKey = "/etc/letsencrypt/live/speedtest.wingard.pro/privkey.pem"; root = "/opt/openspeedtest"; locations."/" = { index = "index.html"; tryFiles = "$uri $uri/ /index.html"; }; locations."~ \\.php$" = { extraConfig = '' fastcgi_pass unix:/run/phpfpm-openspeedtest.sock; fastcgi_index index.php; include ${pkgs.nginx}/conf/fastcgi.conf; fastcgi_param SCRIPT_FILENAME /opt/openspeedtest$fastcgi_script_name; ''; }; }; "speedtest-http" = { listen = [ { addr = "0.0.0.0"; port = 8084; } ]; root = "/opt/openspeedtest"; locations."/" = { index = "index.html"; tryFiles = "$uri $uri/ /index.html"; }; locations."~ \\.php$" = { extraConfig = '' fastcgi_pass unix:/run/phpfpm-openspeedtest.sock; fastcgi_index index.php; include ${pkgs.nginx}/conf/fastcgi.conf; fastcgi_param SCRIPT_FILENAME /opt/openspeedtest$fastcgi_script_name; ''; }; }; }; }; ############################################################ ## ## ## 6: Users ## ## ## ############################################################ ## setting up sudo wheel group security.sudo.extraRules = [ { groups = [ "wheel" ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ]; } ]; ## Harley users.users.harley = { isNormalUser = true; shell = lib.mkForce pkgs.zsh; extraGroups = [ "wheel" "networkmanager" "docker" "input" "uinput" "video"]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH4OAJ8iC7CQIcedVbU86xgoL4YkMWAG9bU6aj9v4Skb harley@utumno" ]; }; ## Roman users.users.roman = { isNormalUser = true; description = "Roman"; home = "/home/roman/"; createHome = true; shell = pkgs.bash; extraGroups = [ "wheel" "users" ]; openssh.authorizedKeys.keys = [ " " ]; }; ## The Ephemeral user and filesystem ## The actual Ephemeral user users.users.atomic = { isNormalUser = true; description = "Ephemeral User - home directory inside a tmpfs"; home = "/home/atomic"; group = "users"; createHome = false; extraGroups = [ "wheel" ]; shell = lib.mkForce pkgs.zsh; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH4OAJ8iC7CQIcedVbU86xgoL4YkMWAG9bU6aj9v4Skb harley@utumno" ]; }; ## filesystem for the Ephemeral user fileSystems."/home/atomic" = { device = "tmpfs"; fsType = "tmpfs"; options = [ "mode=0700" "uid=1001" "gid=100" "noatime" ]; }; ## Populate the Ephemeral user from seed on boot systemd.services.populate-atomic-home = { description = " Populate atomic user's tmpfs home from seed"; after = [ "home-atomic.mount" ]; requires = [ "home-atomic.mount" ]; wantedBy = [ "home-atomic.mount" "systemd-logind.service" ]; script = '' cp -rT /home/.atomic-persist /home/atomic chown -R 1001:100 /home/atomic ''; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; }; ## Periodic Ephemeral home cleaner (reseed from skeleton) systemd.services.atomic-home-cleaner = { description = "Wipe atomic home if user has no active logind sessions"; script = '' if ! pgrep -u atomic >/dev/null 2>&1; then umount /home/atomic/mnt 2>/dev/null || true rm -rf /home/atomic/.??* /home/atomic/** 2>/dev/null cp -rT /home/.atomic-persist/ /home/atomic/ chown -R 1001:100 /home/atomic/ fi ''; serviceConfig.Type = "oneshot"; }; systemd.timers.atomic-home-cleaner = { description = "Check every 2 min if atomic user's sessions ended"; wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = "1min"; OnUnitActiveSec = "30s"; }; }; ## One-shot service to unmount and re-populate atomic's tmpfs home systemd.services.atomic-fresh = { description = "Wipe and re-populate atomic's tmpfs home"; after = [ "home-atomic.mount" ]; script = '' loginctl terminate-user atomic 2>/dev/null || true sleep 1 rm -rf /home/atomic/.??* /home/atomic/** 2>/dev/null || true umount /home/atomic 2>/dev/null || true mount /home/atomic cp -rT /home/.atomic-persist/ /home/atomic/ chown -R 1001:100 /home/atomic/ ''; serviceConfig.Type = "oneshot"; path = [ pkgs.util-linux ]; serviceConfig.User = "root"; }; ############################################################ ## ## ## 7: General Packages ## ## ## ############################################################ environment.systemPackages = with pkgs; [ ## Cli tools vim wget curl progress git btop neovim tmux lsof bat ncdu nvtopPackages.full fastfetch unzip unrar p7zip xclip testdisk btdu ## Games lutris rpcs3 mednafen mednafen-server mednaffe dolphin-emu ## System adwaita-icon-theme tela-circle-icon-theme sshfs sshpass pciutils usbutils python312 (pkgs.kdePackages.bluedevil) gtkgreet cage guake android-tools patool pv ghostscript imagemagick nodejs go deno socat fzf smartmontools shadow ripgrep fd jq tree qdirstat uv firefox obsidian ## Multimedia mpv geeqie ffmpeg yt-dlp ## Virtual display for Sunshine headless streaming (krfb-virtualmonitor) kdePackages.krfb ]; ############################################################ ## ## ## 8) Services ## ## ## ############################################################ ## Hermes WebUI (port 8787) #systemd.services.hermes-webui = { # description = "Hermes Web UI"; # after = [ "network-online.target" ]; # wants = [ "network-online.target" ]; # wantedBy = [ "multi-user.target" ]; # environment = { # HERMES_WEBUI_HOST = "0.0.0.0"; # HERMES_WEBUI_PORT = "8787"; # HERMES_HOME = "/storage/8TB/Backups/Agents/.hermes"; # HERMES_WEBUI_STATE_DIR = "/storage/8TB/Backups/Agents/.hermes/webui"; # SEARXNG_URL = "http://10.0.1.49:8888"; # }; # serviceConfig = { # Type = "simple"; # User = "harley"; # WorkingDirectory = "/opt/hermes-webui"; # ExecStart = "/opt/hermes-webui/venv/bin/python server.py"; # Restart = "on-failure"; # RestartSec = 5; # }; # }; ## SearXNG meta search engine (Port 8888) services.searx = { enable = true; openFirewall = true; redisCreateLocally = true; settings = { general.instance_name = "Utumno Search"; search = { safe_search = 0; formats = [ "html" "json" ]; autocomplete = ""; }; server = { port = 8888; bind_address = "0.0.0.0"; secret_key = "@SEARXNG_SECRET@"; limiter = false; method = "POST"; image_proxy = false; }; ui = { default_theme = "simple"; theme_args.simple_style = "dark"; query_in_title = false; }; outgoing = { request_timeout = 5.0; max_request_timeout = 15.0; pool_connections = 100; pool_maxsize = 20; enable_http2 = true; }; }; environmentFile = "/opt/searxng/secrets.env"; }; ## Gitea (Port 3010) services.gitea = { enable = true; stateDir = "/storage/8TB/Backups/Gitea"; repositoryRoot = "/storage/8TB/Backups/Gitea/repositories"; database.type = "sqlite3"; settings = { server = { DOMAIN = "10.0.1.49"; ROOT_URL = "http://10.0.1.49:3010"; HTTP_PORT = 3010; SSH_PORT = 222; DISABLE_SSH = false; LFS_START_SERVER = false; }; service = { DISABLE_REGISTRATION = false; REQUIRE_SIGNIN_VIEW = false; }; security.INSTALL_LOCK = true; }; }; ## Kiwix ZIM server (port 8098) services.kiwix-serve = { enable = true; port = 8098; openFirewall = true; library = { # Update paths when ZIM files are added/removed wikipedia = "/storage/20TB/Media/Kiwix/wikipedia_en_all_maxi_2026-02.zim"; archlinux = "/storage/20TB/Media/Kiwix/archlinux_en_all_maxi_2025-08.zim"; ifixit = "/storage/20TB/Media/Kiwix/ifixit_en_all_2025-06.zim"; khanacademy = "/storage/20TB/Media/Kiwix/khanacademy_en_all_2023-03.zim"; survivorlibrary = "/storage/20TB/Media/Kiwix/survivorlibrary.com_en_all_2025-06.zim"; urbanprepper = "/storage/20TB/Media/Kiwix/urban-prepper_en_all_2025-06.zim"; anonymousplanet = "/storage/20TB/Media/Kiwix/anonymousplanet.org_en_all_2025-08.zim"; basedcooking = "/storage/20TB/Media/Kiwix/based.cooking_en_all_2025-08.zim"; }; extraArgs = [ "--skipInvalid" ]; }; ## OpenSpeedTest (Port 8084) services.phpfpm.pools.openspeedtest = { user = "nginx"; group = "nginx"; settings = { pm = "dynamic"; "pm.max_children" = 5; "pm.start_servers" = 2; "pm.min_spare_servers" = 1; "pm.max_spare_servers" = 3; "listen" = "/run/phpfpm-openspeedtest.sock"; }; }; ## Immich (Port 2283) #services.immich = { #enable = true; #host = "10.10.10.1"; #mediaLocation = "/storage/8TB/Documents/immich"; #port = 2283; #openFirewall = true; #database.enable = true; #redis.enable = true; #}; ## Roku Remote (Port 7777) ## btop-web system monitor (Port 8777) systemd.services.btop-web = { description = "btop-style web system monitor"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; User = "harley"; WorkingDirectory = "/opt/btop-web"; ExecStart = "${pkgs.python3}/bin/python server.py"; Restart = "always"; RestartSec = 5; }; }; systemd.services.roku-remote = { description = "Roku TV Web Remote"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; User = "harley"; WorkingDirectory = "/opt/roku-remote"; ExecStart = "${pkgs.python3}/bin/python server.py"; Restart = "on-failure"; RestartSec = 5; }; }; ##Sunshine services.sunshine = { enable = true; autoStart = true; capSysAdmin = true; # only needed for Wayland -- omit this when using with Xorg openFirewall = true; }; ## uninput enable for Sunshine. hardware.uinput.enable = true; ## ## ## 8.1: Docker ## ## virtualisation.docker = { enable = true; # Allow non-root users (harley is in docker group) enableOnBoot = true; # Use the overlay2 storage driver (default on modern kernels) storageDriver = "overlay2"; # Auto-prune unused data autoPrune.enable = true; autoPrune.dates = "weekly"; }; ## Firecrawl web-scraper (Port 3002) systemd.services.firecrawl = { description = "Firecrawl web scraping stack"; after = [ "docker.service" "network-online.target" ]; wants = [ "docker.service" "network-online.target" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.docker ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; WorkingDirectory = "/opt/firecrawl"; ExecStart = "${pkgs.docker}/bin/docker compose up -d"; ExecStop = "${pkgs.docker}/bin/docker compose down"; }; }; ########## ########## ########## ########## ########## 8.2: ARRS ########## ########## ########## ########## ########## ## PIA VPN + qBittorrent (Port 8088) + SOCKS5 (Port 1080) (Docker compose) systemd.services.pia-qbit = { description = "PIA VPN + qBittorrent + SOCKS5 proxy stack"; after = [ "docker.service" "network-online.target" ]; wants = [ "docker.service" "network-online.target" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.docker ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; WorkingDirectory = "/opt/pia-qbit"; ExecStart = "${pkgs.docker}/bin/docker compose up -d"; ExecStop = "${pkgs.docker}/bin/docker compose down"; # Give VPN time to establish before declaring "done" ExecStartPost = "${pkgs.coreutils}/bin/sleep 10"; }; }; ## Bitmagnet (Port 3333) #services.bitmagnet = { # enable = true; #openFirewall = true; #settings = { #http_server.local_address = ":3333"; #dht_server.port = 3334; #postgres = { #name = "bitmagnet"; #user = "bitmagnet"; #password = ""; #}; #}; #}; #services.postgresql = { #dataDir = "/storage/20TB/Computer-Related/Bitmagnet-data"; #package = pkgs.postgresql_16; #}; ## Jellyfin (Port 8096) services.jellyfin = { enable = true; dataDir = "/storage/8TB/arrs-tmp/jellyfin"; cacheDir = "/storage/8TB/arrs-tmp/jellyfin-cache"; openFirewall = true; }; ## Prowlarr (port 9696) services.prowlarr = { enable = true; dataDir = "/storage/8TB/arrs-tmp/prowlarr"; openFirewall = true; }; ## Sonarr (port 8989) services.sonarr = { enable = true; dataDir = "/storage/8TB/arrs-tmp/sonarr"; openFirewall = true; }; ## Radarr (port 7878) services.radarr = { enable = true; dataDir = "/storage/8TB/arrs-tmp/radarr"; openFirewall = true; }; ## SABnzbd (port 8180) fileSystems."/var/lib/sabnzbd" = { device = "/storage/8TB/arrs-tmp/sabnzbd"; options = [ "bind" "noauto" ]; fsType = "none"; }; services.sabnzbd = { enable = true; openFirewall = true; settings = { host = "0.0.0.0"; port = 8180; misc = { host = "0.0.0.0"; port = 8180; enable_https = false; html_login = true; inet_exposure = 0; auto_browser = false; config_lock = false; check_new_rel = false; cache_limit = ""; }; }; }; ############################################################ ## ## ## 9: Customization ## ## ## ############################################################ ## ## ## 9.1: Keyd keyboard remappings ## ## services.keyd = { enable = true; keyboards = { default = { ids = [ "*" ]; settings = { main = { esc = "capslock"; capslock = "overload(nav, esc)"; }; nav = { w = "up"; a = "left"; s = "down"; d = "right"; b = "C-left"; u = "pageup"; x = "delete"; g = "home"; n = "end"; h = "left"; j = "down"; k = "up"; l = "right"; space = "capslock"; }; }; }; q = { ids = [ "*" ]; settings = { main = { esc = "capslock"; capslock = "overload(nav, esc)"; }; nav = { w = "up"; a = "left"; s = "down"; d = "right"; h = "left"; j = "down"; k = "up"; l = "right"; space = "capslock"; }; }; }; }; }; ## ## ## 9.2 Enviroment Variables ## ## environment.variables = { GTK_THEME = "Adwaita:dark"; GTK_ICON_THEME = "Tela-circle-dark"; HERMES_HOME = "/storage/8TB/Backups/Agents/.hermes"; }; ## ZSH with Oh-My-Zsh programs.zsh.enable = true; programs.zsh.ohMyZsh = { enable = true; theme = "jonathan"; plugins = [ "git" "sudo" "web-search" "history" "extract" "colored-man-pages" ]; customPkgs = [ (pkgs.runCommand "jonathan-zsh-theme" { themeFile = builtins.readFile ./jonathan.zsh-theme; passAsFile = [ "themeFile" ]; } '' mkdir -p $out/share/zsh/themes cp "$themeFilePath" $out/share/zsh/themes/jonathan.zsh-theme '') ]; }; programs.zsh.syntaxHighlighting.enable = true; programs.zsh.interactiveShellInit = '' source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh ''; programs.zsh.promptInit = '' bindkey '^F' autosuggest-accept bindkey '^[[C' autosuggest-accept ''; programs.zsh.shellAliases = { cl = "clear"; tt = "tmux"; tta = "tmux attach"; ttls = "tmux ls"; xclipp = "xclip -selection clipboard"; palantir = "ssh palantir"; rcp = "rsync -avP --partial --append"; }; # Make theme packages available to all users environment.sessionVariables = { XDG_DATA_DIRS = [ "${pkgs.tela-circle-icon-theme}/share/icons" "${pkgs.catppuccin}/share/plasma" ]; }; ############################################################ ## ## ## ## ## ## ############################################################ ## ── State version ──────────────────────────────────────── system.stateVersion = "26.11"; }