diff --git a/flake.nix b/flake.nix index 4cd8137..5b613e8 100644 --- a/flake.nix +++ b/flake.nix @@ -105,6 +105,7 @@ ./hosts/spindle-hel/services/openbao/openbao.nix ./hosts/spindle-hel/services/openbao/proxy.nix ./hosts/spindle-hel/services/spindle.nix + ./hosts/spindle-hel/services/cache.nix ./hosts/spindle-hel/services/nginx.nix ]; target = "135.181.240.228"; diff --git a/hosts/spindle-hel/services/cache.nix b/hosts/spindle-hel/services/cache.nix new file mode 100644 index 0000000..ae2baad --- /dev/null +++ b/hosts/spindle-hel/services/cache.nix @@ -0,0 +1,88 @@ +{pkgs, ...}: +let + oneGb = 1024 * 1024 * 1024; + maxFreedPerRun = 50 * oneGb; + startGcAt = 94; + stopGcAt = 88; + + port = 5000; +in +{ + services.harmonia = { + enable = true; + + signKeyPaths = [ + "/var/lib/secrets/harmonia.secret" + ]; + + settings = { + bind = "0.0.0.0:${toString port}"; + workers = 4; + max_connection_rate = 256; + priority = 50; + enable_compression = true; + }; + }; + + networking.firewall.interfaces."tailscale0".allowedTCPPorts = [port]; + + # todo(dawn): ideally spindle should record all uploaded paths so we can + # have retention based cleanup instead of this, because nix doesn't cleanup + # retention based (this would also allow us to limit cache per-user and so on + # though so its useful anyway) + systemd.services.nix-store-pressure-gc = { + description = "garbage collect nix store under disk pressure"; + + path = [ + pkgs.bash + pkgs.coreutils + pkgs.nix + ]; + + serviceConfig = { + Type = "oneshot"; + Nice = 19; + IOSchedulingClass = "idle"; + }; + + script = '' + set -euo pipefail + + read -r size used percent < <( + df -B1 --output=size,used,pcent /nix/store | tail -n 1 + ) + + usage="''${percent%\%}" + usage="''${usage//[^0-9]/}" + + if [ "$usage" -lt "${toString startGcAt}" ]; then + exit 0 + fi + + target_used=$(( size * ${toString stopGcAt} / 100 )) + # only free up to our target when possible + bytes_to_free=$(( used - target_used )) + if [ "$bytes_to_free" -le 0 ]; then + exit 0 + fi + max_freed="${toString maxFreedPerRun}" + if [ "$bytes_to_free" -gt "$max_freed" ]; then + bytes_to_free="$max_freed" + fi + + echo "/nix/store is ''${usage}% full, so freeing up to $bytes_to_free bytes" + nix-collect-garbage --max-freed "$bytes_to_free" + ''; + }; + + systemd.timers.nix-store-pressure-gc = { + wantedBy = ["timers.target"]; + + timerConfig = { + OnBootSec = "15m"; + OnUnitActiveSec = "15m"; + RandomizedDelaySec = "5m"; + Persistent = true; + }; + }; +} diff --git a/hosts/spindle-hel/services/nginx.nix b/hosts/spindle-hel/services/nginx.nix index 4e94055..de08a3c 100644 --- a/hosts/spindle-hel/services/nginx.nix +++ b/hosts/spindle-hel/services/nginx.nix @@ -1,30 +1,21 @@ -{ +{config, ...}: { services.nginx = { enable = true; + recommendedProxySettings = true; virtualHosts = { - "spindle.tangled.sh" = { + "spindle.tangled.sh" = let + spindleAddr = "http://${config.services.tangled.spindle.server.listenAddr}"; + in { forceSSL = true; enableACME = true; - locations."/" = { - proxyPass = "http://127.0.0.1:6555"; - }; + locations."/".proxyPass = spindleAddr; locations."/events" = { - proxyPass = "http://127.0.0.1:6555"; - extraConfig = '' - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - ''; + proxyPass = spindleAddr; + proxyWebsockets = true; }; locations."/logs/" = { - proxyPass = "http://127.0.0.1:6555"; - extraConfig = '' - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - ''; + proxyPass = spindleAddr; + proxyWebsockets = true; }; }; };