1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.caddy;
7 configFile = pkgs.writeText "Caddyfile" cfg.config;
8in {
9 options.services.caddy = {
10 enable = mkEnableOption "Caddy web server";
11
12 config = mkOption {
13 default = "";
14 example = ''
15 example.com {
16 gzip
17 minify
18 log syslog
19
20 root /srv/http
21 }
22 '';
23 type = types.lines;
24 description = "Verbatim Caddyfile to use";
25 };
26
27 ca = mkOption {
28 default = "https://acme-v02.api.letsencrypt.org/directory";
29 example = "https://acme-staging-v02.api.letsencrypt.org/directory";
30 type = types.string;
31 description = "Certificate authority ACME server. The default (Let's Encrypt production server) should be fine for most people.";
32 };
33
34 email = mkOption {
35 default = "";
36 type = types.string;
37 description = "Email address (for Let's Encrypt certificate)";
38 };
39
40 agree = mkOption {
41 default = false;
42 type = types.bool;
43 description = "Agree to Let's Encrypt Subscriber Agreement";
44 };
45
46 dataDir = mkOption {
47 default = "/var/lib/caddy";
48 type = types.path;
49 description = ''
50 The data directory, for storing certificates. Before 17.09, this
51 would create a .caddy directory. With 17.09 the contents of the
52 .caddy directory are in the specified data directory instead.
53 '';
54 };
55
56 package = mkOption {
57 default = pkgs.caddy;
58 defaultText = "pkgs.caddy";
59 type = types.package;
60 description = "Caddy package to use.";
61 };
62 };
63
64 config = mkIf cfg.enable {
65 systemd.services.caddy = {
66 description = "Caddy web server";
67 after = [ "network-online.target" ];
68 wantedBy = [ "multi-user.target" ];
69 environment = mkIf (versionAtLeast config.system.stateVersion "17.09")
70 { CADDYPATH = cfg.dataDir; };
71 serviceConfig = {
72 ExecStart = ''
73 ${cfg.package.bin}/bin/caddy -root=/var/tmp -conf=${configFile} \
74 -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
75 '';
76 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
77 Type = "simple";
78 User = "caddy";
79 Group = "caddy";
80 Restart = "on-failure";
81 StartLimitInterval = 86400;
82 StartLimitBurst = 5;
83 AmbientCapabilities = "cap_net_bind_service";
84 CapabilityBoundingSet = "cap_net_bind_service";
85 NoNewPrivileges = true;
86 LimitNPROC = 64;
87 LimitNOFILE = 1048576;
88 PrivateTmp = true;
89 PrivateDevices = true;
90 ProtectHome = true;
91 ProtectSystem = "full";
92 ReadWriteDirectories = cfg.dataDir;
93 };
94 };
95
96 users.users.caddy = {
97 group = "caddy";
98 uid = config.ids.uids.caddy;
99 home = cfg.dataDir;
100 createHome = true;
101 };
102
103 users.groups.caddy.gid = config.ids.uids.caddy;
104 };
105}