{ description = "Flake for server muffin"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; lanzaboote = { url = "github:nix-community/lanzaboote"; inputs.nixpkgs.follows = "nixpkgs"; }; nixos-hardware.url = "github:NixOS/nixos-hardware/master"; nix-minecraft = { url = "github:Infinidoge/nix-minecraft"; inputs.nixpkgs.follows = "nixpkgs"; }; vpn-confinement.url = "github:Maroka-chan/VPN-Confinement"; nixpkgs-qbt.url = "github:NixOS/nixpkgs/pull/287923/head"; 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"; }; llamacpp = { url = "github:ggml-org/llama.cpp"; inputs.nixpkgs.follows = "nixpkgs"; }; srvos = { url = "github:nix-community/srvos"; inputs.nixpkgs.follows = "nixpkgs"; }; deploy-rs = { url = "github:serokell/deploy-rs"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, nix-minecraft, nixos-hardware, vpn-confinement, nixpkgs-qbt, home-manager, lanzaboote, disko, srvos, deploy-rs, ... }@inputs: let username = "primary"; hostname = "muffin"; eth_interface = "enp4s0"; service_configs = rec { zpool_ssds = "tank"; zpool_hdds = "hdds"; torrents_path = "/torrents"; services_dir = "/${zpool_ssds}/services"; music_dir = "/${zpool_ssds}/music"; torrent_group = "media"; ports = { https = 443; jellyfin = 8096; # no services.jellyfin option for this torrent = 6011; bitmagnet = 3333; owntracks = 3825; gitea = 2283; immich = 2284; soulseek_web = 5030; soulseek_listen = 50300; llama_cpp = 8991; }; https = { certs = services_dir + "/http_certs"; # TODO! generate website from repo directly using hugo data_dir = services_dir + "/http"; domain = "gardling.com"; wg_ip = "192.168.15.1"; matrix_hostname = "matrix.${service_configs.https.domain}"; }; gitea = { dir = services_dir + "/gitea"; domain = "git.${https.domain}"; }; postgres = { socket = "/run/postgresql"; dataDir = "${service_configs.services_dir}/sql"; }; immich = { dir = services_dir + "/immich"; }; minecraft = { parent_dir = services_dir + "/minecraft"; server_name = "main"; }; torrent = { SavePath = torrents_path; TempPath = torrents_path + "/incomplete"; }; jellyfin = { dataDir = services_dir + "/jellyfin"; cacheDir = services_dir + "/jellyfin_cache"; }; owntracks = { data_dir = services_dir + "/owntracks"; }; slskd = rec { base = "/var/lib/slskd"; downloads = base + "/downloads"; incomplete = base + "/incomplete"; }; }; serviceMountDeps = serviceName: dirs: pkgs: { systemd.services."${serviceName}_mounts" = { unitConfig.Wants = "zfs.target"; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = let lib = nixpkgs.lib; in "${lib.getExe pkgs.bash} -c \"${lib.getExe pkgs.zfs} get mounted | ${lib.getExe pkgs.gnugrep} yes | ${lib.getExe pkgs.gawk} '{print $1}' | while read i; do ${lib.getExe pkgs.zfs} get mountpoint \$i | ${lib.getExe pkgs.gawk} 'FNR==2 {print \$3}'; done | ${lib.getExe pkgs.gnugrep} '${lib.strings.concatStringsSep "\|" dirs}' | ${pkgs.coreutils}/bin/wc -l | ${lib.getExe pkgs.gnugrep} -q ${toString (lib.length dirs)}\""; }; }; systemd.services.${serviceName} = { wants = [ "${serviceName}_mounts.service" ]; }; }; in { formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt-rfc-style; nixosConfigurations.${hostname} = nixpkgs.lib.nixosSystem { specialArgs = rec { inherit username hostname eth_interface service_configs inputs serviceMountDeps ; # stolen from: https://stackoverflow.com/a/42398526 optimizeWithFlags = pkg: flags: nixpkgs.lib.overrideDerivation pkg ( old: let newflags = nixpkgs.lib.foldl' (acc: x: "${acc} ${x}") "" flags; oldflags = if (nixpkgs.lib.hasAttr "NIX_CFLAGS_COMPILE" old) then "${old.NIX_CFLAGS_COMPILE}" else ""; in { NIX_CFLAGS_COMPILE = "${oldflags} ${newflags}"; # stdenv = pkgs.clang19Stdenv; } ); optimizePackage = pkg: optimizeWithFlags pkg [ "-O3" "-march=znver3" "-mtune=znver3" ]; }; modules = [ # SAFETY! make sure no ports collide ( { lib, ... }: { config = { assertions = [ { assertion = let ports = lib.attrValues service_configs.ports; uniquePorts = lib.unique ports; in (lib.length ports) == (lib.length uniquePorts); message = "Duplicate ports detected in 'ports' configuration"; } ]; }; } ) # sets up things like the watchdog srvos.nixosModules.server # diff terminal support srvos.nixosModules.mixins-terminfo ./disk-config.nix disko.nixosModules.disko ./configuration.nix vpn-confinement.nixosModules.default # import the `services.qbittorrent` module (nixpkgs-qbt + "/nixos/modules/services/torrent/qbittorrent.nix") # get nix-minecraft working! nix-minecraft.nixosModules.minecraft-servers { nixpkgs.overlays = [ nix-minecraft.overlay ]; } lanzaboote.nixosModules.lanzaboote home-manager.nixosModules.home-manager ( { pkgs, username, home-manager, stateVersion, ... }: { home-manager.users.${username} = import ./home.nix; } ) ] ++ (with nixos-hardware.nixosModules; [ common-cpu-amd-pstate common-cpu-amd-zenpower common-pc-ssd common-gpu-intel ]); }; deploy.nodes.muffin = { hostname = "server-public"; profiles.system = { sshUser = "root"; user = "root"; path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.muffin; }; }; }; }