1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6 cfg = config.services.nix-serve;
7in
8{
9 options = {
10 services.nix-serve = {
11 enable = mkEnableOption "nix-serve, the standalone Nix binary cache server";
12
13 port = mkOption {
14 type = types.port;
15 default = 5000;
16 description = ''
17 Port number where nix-serve will listen on.
18 '';
19 };
20
21 bindAddress = mkOption {
22 type = types.str;
23 default = "0.0.0.0";
24 description = ''
25 IP address where nix-serve will bind its listening socket.
26 '';
27 };
28
29 package = mkPackageOption pkgs "nix-serve" { };
30
31 openFirewall = mkOption {
32 type = types.bool;
33 default = false;
34 description = "Open ports in the firewall for nix-serve.";
35 };
36
37 secretKeyFile = mkOption {
38 type = types.nullOr types.str;
39 default = null;
40 description = ''
41 The path to the file used for signing derivation data.
42 Generate with:
43
44 ```
45 nix-store --generate-binary-cache-key key-name secret-key-file public-key-file
46 ```
47
48 For more details see {manpage}`nix-store(1)`.
49 '';
50 };
51
52 extraParams = mkOption {
53 type = types.separatedString " ";
54 default = "";
55 description = ''
56 Extra command line parameters for nix-serve.
57 '';
58 };
59 };
60 };
61
62 config = mkIf cfg.enable {
63 nix.settings = lib.optionalAttrs (lib.versionAtLeast config.nix.package.version "2.4") {
64 extra-allowed-users = [ "nix-serve" ];
65 };
66
67 systemd.services.nix-serve = {
68 description = "nix-serve binary cache server";
69 after = [ "network.target" ];
70 wantedBy = [ "multi-user.target" ];
71
72 path = [ config.nix.package.out pkgs.bzip2.bin ];
73 environment.NIX_REMOTE = "daemon";
74
75 script = ''
76 ${lib.optionalString (cfg.secretKeyFile != null) ''
77 export NIX_SECRET_KEY_FILE="$CREDENTIALS_DIRECTORY/NIX_SECRET_KEY_FILE"
78 ''}
79 exec ${cfg.package}/bin/nix-serve --listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}
80 '';
81
82 serviceConfig = {
83 Restart = "always";
84 RestartSec = "5s";
85 User = "nix-serve";
86 Group = "nix-serve";
87 DynamicUser = true;
88 LoadCredential = lib.optionalString (cfg.secretKeyFile != null)
89 "NIX_SECRET_KEY_FILE:${cfg.secretKeyFile}";
90 };
91 };
92
93 networking.firewall = mkIf cfg.openFirewall {
94 allowedTCPPorts = [ cfg.port ];
95 };
96 };
97}