# This serves a local binary cache. If the request comes from my home network, # it will set its priority higher than cache.nixos.org (which has a priority of # 40), so local devices get a faster binary cache. If the request coes from # outside my home network, it will set its priority lower, only store paths # exclusive to this cache will be substituted. # This only works well when a host does not change its “location”, since nix # caches binary caches locally (per-user, also for root!) in # ${XDG_CACHE_HOME:-$HOME/.cache}/.cache/nix/binary-cache-v6.sqlite and does # not re-check or invalidate them. Devices that often are not at home should # ensure that the cached priority is 50 to avoid slow substitutions. { config, lib, pkgs, ... }: let binaryCachePath = "/data/cache/nix-binary-cache"; in { sops.secrets.nix-binary-cache-htpasswd = { owner = "nginx"; sopsFile = ../secrets.yaml; }; services.nginx = { appendHttpConfig = '' geo $nix_binary_cache_priority { default 50; 192.168.100.0/24 30; 2001:470:1f0b:abc::/64 30; } ''; virtualHosts."nix-cache.sbruder.de" = rec { enableACME = true; forceSSL = true; root = binaryCachePath; locations = { "/nix-cache-info" = { return = "200 \"StoreDir: /nix/store\\nPriority: $nix_binary_cache_priority\\n\""; }; "/".extraConfig = '' log_not_found off; client_max_body_size 5G; # WebDAV (for uploading) dav_methods PUT DELETE; create_full_put_path on; # nar/ does not exist by default dav_access user:rw group:r all:r; # same filesystem for temporary files client_body_temp_path ${root}/.upload-tmp; limit_except GET { auth_basic "restricted upload"; auth_basic_user_file ${config.sops.secrets.nix-binary-cache-htpasswd.path}; } # workaround for nginx dropping parent headers # see https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md ${lib.concatStringsSep "\n" (lib.filter (lib.hasPrefix "add_header ") (lib.splitString "\n" config.services.nginx.commonHttpConfig))} add_header Access-Control-Allow-Origin https://hydra.sbruder.de; ''; "/nix/store/".proxyPass = "http://localhost:${config.systemd.services.nar-serve.environment.PORT}"; }; }; }; systemd.services.nginx.serviceConfig.ReadWritePaths = lib.singleton binaryCachePath; # TODO 21.05: Replace with upstream module systemd.services.nar-serve = let # TODO: remove once new version is released and in nixpkgs nar-serve = pkgs.unstable.nar-serve.overrideAttrs (o: o // { version = "unstable-2021-04-08"; src = pkgs.fetchFromGitHub { owner = "numtide"; repo = "nar-serve"; rev = "4243b0efa41910dfa4be8b9936ae460699d3f8f0"; sha256 = "0mjs3yilf5rixm67wk4h4jji54dsc0w3vfxd561pvfbxplbmgh3c"; }; }); in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment = { PORT = "8383"; NAR_CACHE_URL = "file://${binaryCachePath}"; }; serviceConfig = { Restart = "always"; RestartSec = "5s"; ExecStart = "${nar-serve}/bin/nar-serve"; DynamicUser = true; StandardOutput = "null"; # nar-server logs multiple lines on every request }; }; }