{ config, pkgs, lib, ... }: let mkVHost = baseUrl: { service, port, }: { name = "${service}.${baseUrl}"; value = { listenAddresses = ["100.76.159.53"]; extraConfig = '' tls { dns porkbun { api_key {env.PORKBUN_API_KEY} api_secret_key {env.PORKBUN_SECRET_KEY} } } reverse_proxy localhost:${builtins.toString port} ''; }; }; mkVHosts = baseUrl: hosts: builtins.listToAttrs (builtins.map (mkVHost baseUrl) hosts); zfsCompatibleKernelPackages = lib.filterAttrs ( name: kernelPackages: (builtins.match "linux_[0-9]+_[0-9]+" name) != null && (builtins.tryEval kernelPackages).success && (!kernelPackages.${config.boot.zfs.package.kernelModuleAttribute}.meta.broken) ) pkgs.linuxKernel.packages; latestKernelPackage = lib.last ( lib.sort (a: b: (lib.versionOlder a.kernel.version b.kernel.version)) ( builtins.attrValues zfsCompatibleKernelPackages ) ); in { imports = [ ../common ./hardware-configuration.nix (import ../../modules).ranni ]; boot.kernelPackages = lib.mkForce latestKernelPackage; boot.loader.systemd-boot.enable = false; boot.loader.grub = { enable = true; efiSupport = false; devices = ["/dev/disk/by-id/ata-ST4000NM0245-1Z2107_ZC1A059L" "/dev/disk/by-id/ata-ST4000NM0245-1Z2107_ZC19X508"]; copyKernels = true; }; boot.supportedFilesystems = ["zfs"]; boot.swraid.enable = true; boot.kernelParams = ["boot.shell_on_fail"]; networking = { hostName = "ranni"; hostId = "00000001"; useDHCP = false; interfaces."enp0s31f6" = { ipv4.addresses = [ { address = "95.216.12.238"; # Hetzner requires /32, see: # https://docs.hetzner.com/robot/dedicated-server/network/net-config-debian-ubuntu/#ipv4. # NixOS automatically sets up a route to the gateway # (but only because we set "networking.defaultGateway.interface" below), see # https://github.com/NixOS/nixops/pull/1032#issuecomment-2763497444 prefixLength = 32; } ]; ipv6.addresses = [ { address = "2a01:4f9:2a:d05::1"; prefixLength = 64; } ]; }; defaultGateway = { address = "95.216.12.193"; # Interface must be given for Hetzner networking to work, see comment above. interface = "enp0s31f6"; }; defaultGateway6 = { address = "fe80::1"; interface = "enp0s31f6"; }; nameservers = [ # cloudflare "1.1.1.1" "2606:4700:4700::1111" "2606:4700:4700::1001" # google "8.8.8.8" "2001:4860:4860::8888" "2001:4860:4860::8844" ]; firewall = { allowedTCPPorts = [80 8448 443]; allowedTCPPortRanges = [ { from = 12500; to = 12515; } ]; allowedUDPPortRanges = [ { from = 12500; to = 12515; } ]; interfaces = { "tailscale0" = { allowedUDPPorts = [41641]; }; }; }; }; services.tailscale.permitCertUid = "caddy"; services.syncthing = { settings = { gui = { insecureSkipHostcheck = true; }; }; guiAddress = "localhost:8387"; }; services = { jellyfin.enable = true; jellyfin.group = "media"; }; users.groups."media".name = "media"; age.secrets = { caddy_porkbun_api_env.file = ../../secrets/caddy_porkbun_api_env.age; danflix_hetzner_storage_box_pub_key.file = ../../secrets/danflix_hetzner_storage_box_pub_key.age; danflix_rclone_config.file = ../../secrets/danflix_rclone_config.age; }; services.sabnzbd = { enable = true; group = "media"; }; containers.radarr = { autoStart = true; bindMounts = { "/data" = { hostPath = "/var/media"; mountPoint = "/var/media"; isReadOnly = false; }; }; config = {config, pkgs, lib, ...}: { services.radarr = { enable = true; user = "root"; group = "root"; }; system.stateVersion = "24.11"; }; }; containers.sonarr = { autoStart = true; bindMounts = { "/data" = { hostPath = "/var/media"; mountPoint = "/var/media"; isReadOnly = false; }; }; config = {config, pkgs, lib, ...}: { services.sonarr = { enable = true; user = "root"; group = "root"; }; system.stateVersion = "24.11"; }; }; services.prowlarr = { enable = true; }; services.caddy = { enable = true; enableReload = false; environmentFile = config.age.secrets.caddy_porkbun_api_env.path; package = pkgs.caddy.withPlugins { plugins = ["github.com/caddy-dns/porkbun@v0.2.1"]; hash = "sha256-X8QbRc2ahW1B5niV8i3sbfpe1OPYoaQ4LwbfeaWvfjg="; }; logFormat = "level INFO"; virtualHosts = (mkVHosts "broccoli.town" [ { service = "radarr"; port = 7878; } { service = "sonarr"; port = 8989; } { service = "sab"; port = 8085; } # { # service = "transmission"; # port = 9091; # } ]) // { "http://ranni:8085" = { listenAddresses = ["100.76.159.53"]; extraConfig = '' reverse_proxy localhost:8085 ''; }; # "danielpatterson.dev" = { # extraConfig = '' # header { # proof proven.lol/de4a14 # } # root * /srv/site/danielpatterson.dev # encode zstd gzip # file_server # ''; # }; "movies.danielpatterson.dev" = { extraConfig = '' reverse_proxy localhost:8096 ''; }; # "git.broccoli.town" = { # extraConfig = '' # reverse_proxy localhost:3030 # ''; # }; }; }; environment.systemPackages = with pkgs; [ helix kitty # For terminfo lazygit ]; system.stateVersion = "24.11"; # Did you read the comment? }