{ inputs, pkgs, lib, ... }: { imports = [ # inputs.impermanence.nixosModules.impermanence inputs.disko.nixosModules.disko ./hardware-configuration.nix ./disko.nix # ./secrets.nix # ./services ]; # System identification networking = { hostName = "odin"; # Generate a unique host ID (you need to replace this with an actual string) # hostId = "12345678"; # Generate with `head -c 8 /etc/machine-id` and place result here useDHCP = lib.mkDefault true; # Firewall configuration for home server # firewall = { # enable = true; # allowedTCPPorts = [ # 22 # SSH # 80 # HTTP # 443 # HTTPS # 2283 # Immich # ]; # }; }; # Boot configuration boot = { # Use systemd-boot for UEFI systems loader = { systemd-boot.enable = true; efi.canTouchEfiVariables = true; grub.devices = [ "/dev/nvme0n1" ]; timeout = 3; }; # Kernel parameters for server workload kernelParams = [ "rootflags=compress=zstd:1,noatime" ]; # Enable KSM for memory efficiency with containers kernel.sysctl = { "kernel.sysrq" = 1; "vm.swappiness" = 10; "net.core.default_qdisc" = "cake"; }; }; # # Impermanence: reset root on boot # initrd.postDeviceCommands = lib.mkAfter '' # # Get device from disko config # DEVICE=/dev/disk/by-id/nvme-KINGSTON_SNV3S1000G_50026B7383CC0908-part2 # # mkdir -p /mnt # mount -o subvol=/ $DEVICE /mnt # # # Create a directory for old roots if it doesn't exist # mkdir -p /mnt/old-roots # # # Move current root to old-roots with timestamp if it exists # if [[ -e /mnt/@root && ! -e /mnt/@root-blank ]]; then # timestamp=$(date --date="@$(stat -c %Y /mnt/@root)" "+%Y-%m-%d_%H:%M:%S") # mv /mnt/@root "/mnt/old-roots/@root-$timestamp" # fi # # # Function to recursively delete subvolumes # delete_subvolume_recursively() { # for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do # delete_subvolume_recursively "/mnt/$i" # done # btrfs subvolume delete "$1" # } # # # Delete old roots older than 30 days # for i in $(find /mnt/old-roots/ -maxdepth 1 -mtime +30); do # delete_subvolume_recursively "$i" # done # # # Create fresh root from blank if needed or create blank if it doesn't exist # if [[ -e /mnt/@root-blank ]]; then # btrfs subvolume delete /mnt/@root || true # btrfs subvolume snapshot /mnt/@root-blank /mnt/@root # else # btrfs subvolume create /mnt/@root-blank # btrfs subvolume create /mnt/@root # fi # # umount /mnt # ''; # }; # # # Hardware optimizations # hardware = { # enableRedistributableFirmware = true; # cpu.amd.updateMicrocode = true; # # # Enable hardware acceleration for media processing # opengl = { # enable = true; # extraPackages = with pkgs; [ # amdvlk # rocm-opencl-icd # ]; # }; # }; # # # Power management for home server # powerManagement = { # enable = true; # cpuFreqGovernor = "ondemand"; # }; # Services configuration services = { # SSH configuration is managed in secrets.nix openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; X11Forwarding = false; }; # hostKeys = [ ]; }; # System monitoring # smartd = { # enable = true; # autodetect = true; # notifications.mail.enable = false; # Configure if you want email alerts # }; # # Time synchronization # timesyncd.enable = true; # # # Btrfs maintenance # btrfs.autoScrub = { # enable = true; # interval = "monthly"; # fileSystems = [ "/" ]; # }; # # # Drive power management and fan control # hddfancontrol = { # enable = false; # settings = { # harddrives = { # disks = [ # "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV023WG" # "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV07RMA" # "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV020CG" # ]; # pwmPaths = [ # "/sys/class/hwmon/hwmon5/pwm1:25:10" # ]; # logVerbosity = "DEBUG"; # }; # }; # }; # Drive spin-down management # hdparm.devices = [ # { # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV023WG"; # spindownTime = 120; # 10 minutes # apmLevel = 127; # } # { # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV07RMA"; # spindownTime = 120; # apmLevel = 127; # } # { # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV020CG"; # spindownTime = 120; # apmLevel = 127; # } # ]; }; # # Automatic garbage collection # nix = { # gc = { # automatic = true; # dates = "weekly"; # options = "--delete-older-than 30d"; # }; # optimise.automatic = true; # }; # # Container runtime # virtualisation = { # docker = { # enable = true; # storageDriver = "btrfs"; # autoPrune = { # enable = true; # dates = "weekly"; # flags = [ "--all" "--force" "--volumes" ]; # }; # }; # }; # System packages environment.systemPackages = with pkgs; [ # System utilities htop btop iotop lsof pciutils usbutils # Network tools curl wget rsync # File system tools btrfs-progs xfsprogs smartmontools hdparm # # Container tools # docker-compose # Storage management snapraid mergerfs # Monitoring lm_sensors nvme-cli ]; # User configuration users = { mutableUsers = false; # Declarative user management users = { # Main user account thomas = { isNormalUser = true; extraGroups = [ "wheel" "users" ]; hashedPassword = "$6$jO/t4PtMb4Ky.goy$2diW2qZjswUAVAzRQqOJ7wfGwD9QInJtUfQYEOOp8hkdhAy6wcccYfIG.gEQniStx7ZkxADNQxQ7pyfUiOqll."; openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5o7LT5wPYWgI8Mvr6RKOv+BcsbQgU7PCw2hheVu17alwF1uFUsAYV5BVQu+uv9uEm/UDsCNhfM6TwI0A1prdmtBz4pKiwXbj7fcdp6DcVOgTsPfawbXEpivtJvlhEatyTsR26MjHKnqpT0BxPvj6Ug6pvRkCYW5d2bWXiY9murmAX6Q5kSyNunkB8PdRTH+S47f7eOdCJY63VBOkkiG8M7XyPwFCDTYiHhbMZcejIdY9mB6kYnMQVRHDznQWiQxrcaE1fD/TY3db9GDcOVoo2aDBOZX7WT2+me67sU8dEK9+nSyhWDzBbEs8knu87ZlKPFwhl4slenRniKhbf22OpicXArtEcjEj0GyDJH5e+ZCIQ4eSQanA7TxnKFlDuaf+Qqx55UT+ya4vJJeik7nkzbRHaE9IoWhhiOaOnaN6kHIxuxB6z7EL3Gk7f78+I/qBaj5df6fgnXM3JBXKa5bRH2wqoSetJAo6EGpEgmU2huB1ktiGlO7BlF5XwSw6cb/KT7NSIXhncgLkCzsDVXxecVQv1FnPISBcp3+ti01ADVf2trgpPDbNTWV40Rgiefie0o2fc6KWAFfum1j5N3WWU+XVVmRjDmKKHiEJBLNKDAe0rQf+tryPW4c5GIN7aFoB+8dYFAuUyLd7Fu3vhZdmcckN5ryHunEc0dKPIiuoVZw==" ]; }; }; }; # # File system mounts for impermanence # fileSystems = { # # Boot partition # "/boot" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-efi"; # fsType = "vfat"; # }; # # # Root filesystem # "/" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@root" "compress=zstd:1" "noatime" ]; # }; # # # Nix store # "/nix" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@nix" "compress=zstd:1" "noatime" ]; # }; # # # Home directory # "/home" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@home" "compress=zstd:1" "noatime" ]; # }; # # # Persistent data # "/persist" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@persist" "compress=zstd:1" "noatime" ]; # neededForBoot = true; # }; # # # Logs # "/logs" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@logs" "compress=zstd:1" "noatime" ]; # }; # # # Services data # "/services" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@services" "compress=zstd:1" "noatime" ]; # }; # # # Database storage - nodatacow for performance # "/databases" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@databases" "compress=zstd:1" "noatime" "nodatacow" ]; # }; # # # Cache storage - nodatacow for performance # "/cache" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@cache" "compress=zstd:1" "noatime" "nodatacow" ]; # }; # # # Container storage - nodatacow for performance # "/containers" = { # device = lib.mkDefault "/dev/disk/by-partlabel/disk-main-root"; # fsType = "btrfs"; # options = [ "subvol=@containers" "compress=zstd:1" "noatime" "nodatacow" ]; # }; # }; # # Persistent directories for impermanence # environment.persistence."/persist" = { # hideMounts = true; # directories = [ # "/etc/nixos" # "/etc/ssh" # "/var/lib/nixos" # "/var/lib/systemd" # "/srv" # ]; # files = [ # "/etc/machine-id" # ]; # users.thomas = { # directories = [ # ".ssh" # ".config" # ]; # }; # }; # System state version system.stateVersion = "25.05"; }