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