From 2dabf2b2cb2faff9bac3f54b7754f45b9aeed9ed Mon Sep 17 00:00:00 2001 From: Kieran Klukas Date: Tue, 12 May 2026 22:11:24 -0400 Subject: [PATCH] feat: add arr stack and such --- flake.lock | 81 +++++++++++++++ flake.nix | 6 ++ lib/services.nix | 8 ++ machines/prattle/default.nix | 168 +++++++++++++++++++++++--------- machines/prattle/facter.json | 2 +- machines/terebithia/default.nix | 25 +++++ secrets/minio.age | 13 +++ secrets/secrets.nix | 6 ++ 8 files changed, 263 insertions(+), 46 deletions(-) create mode 100644 secrets/minio.age diff --git a/flake.lock b/flake.lock index cf0c95b..4de4dcd 100644 --- a/flake.lock +++ b/flake.lock @@ -841,6 +841,29 @@ "type": "github" } }, + "nixarr": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix", + "vpnconfinement": "vpnconfinement", + "website-builder": "website-builder" + }, + "locked": { + "lastModified": 1778346734, + "narHash": "sha256-G5ZyrISExI0L6CqHX/0CrdTVEu9lpIdevhpkYwhGf/E=", + "owner": "nix-media-server", + "repo": "nixarr", + "rev": "476ffae2a09911008847dd5a86c18b8cb484d198", + "type": "github" + }, + "original": { + "owner": "nix-media-server", + "repo": "nixarr", + "type": "github" + } + }, "nixos-facter-modules": { "locked": { "lastModified": 1773858690, @@ -1159,6 +1182,7 @@ "import-tree": "import-tree", "nix-darwin": "nix-darwin", "nix-vscode-extensions": "nix-vscode-extensions", + "nixarr": "nixarr", "nixos-facter-modules": "nixos-facter-modules", "nixpkgs": "nixpkgs_4", "nixpkgs-unstable": "nixpkgs-unstable", @@ -1474,6 +1498,27 @@ "type": "github" } }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixarr", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1775125835, + "narHash": "sha256-2qYcPgzFhnQWchHo0SlqLHrXpux5i6ay6UHA+v2iH4U=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "75925962939880974e3ab417879daffcba36c4a3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, "utils": { "inputs": { "systems": "systems_4" @@ -1492,6 +1537,21 @@ "type": "github" } }, + "vpnconfinement": { + "locked": { + "lastModified": 1767604552, + "narHash": "sha256-FddhMxnc99KYOZ/S3YNqtDSoxisIhVtJ7L4s8XD2u0A=", + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "rev": "a6b2da727853886876fd1081d6bb2880752937f3", + "type": "github" + }, + "original": { + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "type": "github" + } + }, "wakatime-ls": { "inputs": { "gitignore": "gitignore_2", @@ -1514,6 +1574,27 @@ "type": "github" } }, + "website-builder": { + "inputs": { + "nixpkgs": [ + "nixarr", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771957511, + "narHash": "sha256-MxpsyVQguwmeN40gblvcYLtL4xiriGYB6UyP+JergpQ=", + "owner": "rasmus-kirk", + "repo": "website-builder", + "rev": "896af41c1a01f934799356f1f51cfddff2abda82", + "type": "github" + }, + "original": { + "owner": "rasmus-kirk", + "repo": "website-builder", + "type": "github" + } + }, "zig2nix": { "inputs": { "flake-utils": "flake-utils_6", diff --git a/flake.nix b/flake.nix index c9a3e17..94dc7bf 100644 --- a/flake.nix +++ b/flake.nix @@ -124,6 +124,11 @@ inputs.nixpkgs.follows = "nixpkgs-unstable"; }; + nixarr = { + url = "github:nix-media-server/nixarr"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; outputs = @@ -192,6 +197,7 @@ inputs.disko.nixosModules.disko agenix.nixosModules.default inputs.nixos-facter-modules.nixosModules.facter + inputs.nixarr.nixosModules.default { config.facter.reportPath = ./machines/prattle/facter.json; } unstable-overlays ./machines/prattle diff --git a/lib/services.nix b/lib/services.nix index 2c9c38c..95efa06 100644 --- a/lib/services.nix +++ b/lib/services.nix @@ -181,6 +181,14 @@ repository = null; health_url = "https://${config.services.n8n.environment.N8N_HOST or "n8n.dunkirk.sh"}/healthz"; })) + (lib.optional (config.services.minio.enable or false) (mkCustom "minio" { + description = "S3-compatible object storage"; + domain = "s3.dunkirk.sh"; + port = 9001; + runtime = "go"; + repository = null; + health_url = null; + })) ]; serviceList = (lib.mapAttrsToList mkEntry standardServices) ++ emojibotInstances ++ customServices; diff --git a/machines/prattle/default.nix b/machines/prattle/default.nix index d038ae8..2e89324 100644 --- a/machines/prattle/default.nix +++ b/machines/prattle/default.nix @@ -49,6 +49,7 @@ environment.systemPackages = with pkgs; [ # core coreutils + ghostty.terminfo screen bc jq @@ -101,9 +102,11 @@ path = "/home/kierank/.wakatime.cfg"; owner = "kierank"; }; - cloudflare = { - file = ../../secrets/cloudflare.age; - owner = "caddy"; + nordvpn-wg = { + file = ../../secrets/nordvpn-wg.age; + }; + minio = { + file = ../../secrets/minio.age; }; }; @@ -152,6 +155,7 @@ ]; extraGroups = [ "wheel" + "media" ]; }; root.openssh.authorizedKeys.keys = [ @@ -159,7 +163,6 @@ ]; }; - # Allow passwordless sudo for wheel group (needed for deploy-rs) security.sudo.wheelNeedsPassword = false; services.openssh = { @@ -173,7 +176,21 @@ networking.firewall = { enable = true; - allowedTCPPorts = [ 22 80 443 ]; + allowedTCPPorts = [ + 22 + 445 # Samba + 5252 # qBittorrent + 6767 # Bazarr + 7878 # Radarr + 8096 # Jellyfin + 8989 # Sonarr + 9000 # MinIO API + 9001 # MinIO Console + 9696 # Prowlarr + ]; + allowedUDPPorts = [ + 137 138 # Samba NetBIOS + ]; logRefusedConnections = false; rejectPackets = true; }; @@ -183,52 +200,113 @@ useRoutingFeatures = "client"; }; - services.caddy = { + # ── NVIDIA (GT 1030 — Pascal GP108) ────────────────────────────────── + hardware.nvidia = { + open = false; + package = config.boot.kernelPackages.nvidiaPackages.production; + }; + hardware.graphics.enable = true; + services.xserver.videoDrivers = [ "nvidia" ]; + + # ── Nixarr ─────────────────────────────────────────────────────────── + nixarr = { enable = true; - package = pkgs.caddy.withPlugins { - plugins = [ "github.com/caddy-dns/cloudflare@v0.2.2" ]; - hash = "sha256-0qis+BN4of+DV0x4/XfpS7J2kANcm65EewN9v1VNlQs="; - }; - email = "kieran@dunkirk.sh"; - globalConfig = '' - acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN} - ''; - virtualHosts."status.dunkirk.sh" = { - extraConfig = '' - tls { - dns cloudflare {env.CLOUDFLARE_API_TOKEN} - } - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - } - reverse_proxy localhost:3001 { - header_up X-Forwarded-Proto {scheme} - header_up X-Forwarded-For {remote} - } - ''; - }; - extraConfig = '' - # Default response for unhandled domains - :80 { - respond "404 - Looks like this pin is unobtainable" 404 - } - :443 { - respond "404 - Looks like this pin is unobtainable" 404 - } - ''; - }; - - systemd.services.caddy.serviceConfig = { - EnvironmentFile = config.age.secrets.cloudflare.path; - }; - - services.uptime-kuma = { + mediaDir = "/storage/media"; + stateDir = "/storage/.state/nixarr"; + + vpn = { + enable = true; + wgConf = config.age.secrets.nordvpn-wg.path; + }; + + jellyfin = { + enable = true; + openFirewall = true; + }; + + sonarr = { + enable = true; + openFirewall = true; + settings-sync.qbittorrent.enable = true; + }; + + radarr = { + enable = true; + openFirewall = true; + settings-sync.qbittorrent.enable = true; + }; + + prowlarr = { + enable = true; + openFirewall = true; + settings-sync = { + enable-nixarr-apps = true; + sonarr.enable = true; + radarr.enable = true; + }; + }; + + bazarr = { + enable = true; + openFirewall = true; + settings-sync = { + sonarr.enable = true; + radarr.enable = true; + }; + }; + + qbittorrent = { + enable = true; + vpn.enable = true; + openFirewall = true; + }; + }; + + # ── Samba ───────────────────────────────────────────────────────────── + services.samba = { enable = true; + openFirewall = true; settings = { - PORT = "3001"; + global = { + "workgroup" = "WORKGROUP"; + "server string" = "prattle"; + "server role" = "standalone server"; + "map to guest" = "Bad User"; + "hosts allow" = "192.168.0.0/16 100.64.0.0/10 127.0.0.1"; + "hosts deny" = "0.0.0.0/0"; + }; + storage = { + path = "/storage"; + browseable = "yes"; + "read only" = "no"; + "guest ok" = "no"; + "valid users" = "kierank"; + "create mask" = "0664"; + "directory mask" = "0775"; + "force group" = "media"; + }; + media = { + path = "/storage/media"; + browseable = "yes"; + "read only" = "yes"; + "guest ok" = "yes"; + "force group" = "media"; + }; }; }; + services.samba-wsdd = { + enable = true; + openFirewall = true; + }; + + # ── MinIO (S3-compatible) ───────────────────────────────────────────── + services.minio = { + enable = true; + dataDir = [ "/storage/s3" ]; + rootCredentialsFile = config.age.secrets.minio.path; + }; + boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; zramSwap = { diff --git a/machines/prattle/facter.json b/machines/prattle/facter.json index 7e23438..cb9c170 100644 --- a/machines/prattle/facter.json +++ b/machines/prattle/facter.json @@ -567,7 +567,7 @@ "fpu_exception": false, "cpuid_level": 13, "write_protect": false, - "tlb_size": 32765, + "tlb_size": 30308, "clflush_size": 64, "cache_alignment": 64, "address_sizes": { diff --git a/machines/terebithia/default.nix b/machines/terebithia/default.nix index 492b6f9..e728fd1 100644 --- a/machines/terebithia/default.nix +++ b/machines/terebithia/default.nix @@ -574,6 +574,31 @@ ''; }; + # ── Prattle reverse proxies (over Tailscale) ───────────────────────── + services.caddy.virtualHosts."jellyfin.dunkirk.sh" = { + extraConfig = '' + tls { + dns cloudflare {env.CLOUDFLARE_API_TOKEN} + } + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + } + reverse_proxy prattle:8096 + ''; + }; + + services.caddy.virtualHosts."s3.dunkirk.sh" = { + extraConfig = '' + tls { + dns cloudflare {env.CLOUDFLARE_API_TOKEN} + } + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + } + reverse_proxy prattle:9001 + ''; + }; + swapDevices = [{ device = "/var/swapfile"; size = 4096; }]; boot.loader.systemd-boot.enable = true; diff --git a/secrets/minio.age b/secrets/minio.age new file mode 100644 index 0000000..da860df --- /dev/null +++ b/secrets/minio.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-rsa DqcG0Q +Sa4hWy0P8uxkkHvnssgwh044FI5tbSl333knhKWeGnVhyStTvAiNrG+xYTRlgoX0 +QyLjLE2D6xGnFSsumfUiD6rl0M4z4xQbLP4cOljVolOJjKMeyVlLlBmDZ7NW7DG6 +ObFjewXUEvETMk9+2dhy9bYrfYG5aO8vO6xl+dUHs1wi2vcR2ndd5syq1+KC46AR +IBYXg3PQsFPqW1igY0Ut43B4pyh8lOM2IH5p5j0AX8Jk9zOfmjfvEVpJfaaunUvt +7BfWb9DCbaNsH204N1d5q8ZbaQwt3zycCuOgVm6vXXHjB/xgs1Gus9Wq+C3Eg9+t +8xO95ZTq8+QaDgu258PJ2uZVvJEFEMsUbPKC0612Qp5IrmT7GEifwFeX4uHrvFrU +bAUIrIsX9fGIjwld+MV8owX1ulNvmTWAZ23SsQ6wyDXW4wwUJ1nVpF4GrJU4rqQO +O/AiDOJkdAz5KqO94EN3GgPzHp+G5bcfyaOr/T7G0gUqYn1dUry4atuWTQMClPjO + +--- /rLA3GHu9Wm7BPUtz7Oj/GHcEdOoN4tReyo4iGSkO1U +�y� r���2^�-�UX�Q��[����g��x�~!�G�]X!L9di���b#P&�ؕpR=�+?1d8�����:D�]>G��2Qh�'���h=�cܾ�H��F D+� \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 2f27f65..318d2c6 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -90,4 +90,10 @@ in "paperless-oidc.age".publicKeys = [ kierank ]; + "nordvpn-wg.age".publicKeys = [ + kierank + ]; + "minio.age".publicKeys = [ + kierank + ]; } -- 2.51.2