diff options
Diffstat (limited to 'nixos/modules/services/web-servers/caddy.nix')
-rw-r--r-- | nixos/modules/services/web-servers/caddy.nix | 124 |
1 files changed, 92 insertions, 32 deletions
diff --git a/nixos/modules/services/web-servers/caddy.nix b/nixos/modules/services/web-servers/caddy.nix index 0e6e10a5f47..955b9756406 100644 --- a/nixos/modules/services/web-servers/caddy.nix +++ b/nixos/modules/services/web-servers/caddy.nix @@ -5,7 +5,45 @@ with lib; let cfg = config.services.caddy; configFile = pkgs.writeText "Caddyfile" cfg.config; + + tlsConfig = { + apps.tls.automation.policies = [{ + issuer = { + inherit (cfg) ca email; + module = "acme"; + }; + }]; + }; + + adaptedConfig = pkgs.runCommand "caddy-config-adapted.json" { } '' + ${cfg.package}/bin/caddy adapt \ + --config ${configFile} --adapter ${cfg.adapter} > $out + ''; + tlsJSON = pkgs.writeText "tls.json" (builtins.toJSON tlsConfig); + + # merge the TLS config options we expose with the ones originating in the Caddyfile + configJSON = + let tlsConfigMerge = '' + {"apps": + {"tls": + {"automation": + {"policies": + (if .[0].apps.tls.automation.policies == .[1]?.apps.tls.automation.policies + then .[0].apps.tls.automation.policies + else (.[0].apps.tls.automation.policies + .[1]?.apps.tls.automation.policies) + end) + } + } + } + }''; + in pkgs.runCommand "caddy-config.json" { } '' + ${pkgs.jq}/bin/jq -s '.[0] * ${tlsConfigMerge}' ${adaptedConfig} ${tlsJSON} > $out + ''; in { + imports = [ + (mkRemovedOptionModule [ "services" "caddy" "agree" ] "this option is no longer necessary for Caddy 2") + ]; + options.services.caddy = { enable = mkEnableOption "Caddy web server"; @@ -13,15 +51,38 @@ in { default = ""; example = '' example.com { - gzip - minify - log syslog - - root /srv/http + encode gzip + log + root /srv/http } ''; type = types.lines; - description = "Verbatim Caddyfile to use"; + description = '' + Verbatim Caddyfile to use. + Caddy v2 supports multiple config formats via adapters (see <option>services.caddy.adapter</option>). + ''; + }; + + user = mkOption { + default = "caddy"; + type = types.str; + description = "User account under which caddy runs."; + }; + + group = mkOption { + default = "caddy"; + type = types.str; + description = "Group account under which caddy runs."; + }; + + adapter = mkOption { + default = "caddyfile"; + example = "nginx"; + type = types.str; + description = '' + Name of the config adapter to use. + See https://caddyserver.com/docs/config-adapters for the full list. + ''; }; ca = mkOption { @@ -37,12 +98,6 @@ in { description = "Email address (for Let's Encrypt certificate)"; }; - agree = mkOption { - default = false; - type = types.bool; - description = "Agree to Let's Encrypt Subscriber Agreement"; - }; - dataDir = mkOption { default = "/var/lib/caddy"; type = types.path; @@ -50,39 +105,39 @@ in { The data directory, for storing certificates. Before 17.09, this would create a .caddy directory. With 17.09 the contents of the .caddy directory are in the specified data directory instead. + + Caddy v2 replaced CADDYPATH with XDG directories. + See https://caddyserver.com/docs/conventions#file-locations. ''; }; package = mkOption { default = pkgs.caddy; defaultText = "pkgs.caddy"; + example = "pkgs.caddy"; type = types.package; - description = "Caddy package to use."; + description = '' + Caddy package to use. + ''; }; }; config = mkIf cfg.enable { systemd.services.caddy = { description = "Caddy web server"; - # upstream unit: https://github.com/caddyserver/caddy/blob/master/dist/init/linux-systemd/caddy.service + # upstream unit: https://github.com/caddyserver/dist/blob/master/init/caddy.service after = [ "network-online.target" ]; wants = [ "network-online.target" ]; # systemd-networkd-wait-online.service wantedBy = [ "multi-user.target" ]; - environment = mkIf (versionAtLeast config.system.stateVersion "17.09") - { CADDYPATH = cfg.dataDir; }; + startLimitIntervalSec = 14400; + startLimitBurst = 10; serviceConfig = { - ExecStart = '' - ${cfg.package}/bin/caddy -log stdout -log-timestamps=false \ - -root=/var/tmp -conf=${configFile} \ - -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"} - ''; - ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID"; + ExecStart = "${cfg.package}/bin/caddy run --config ${configJSON}"; + ExecReload = "${cfg.package}/bin/caddy reload --config ${configJSON}"; Type = "simple"; - User = "caddy"; - Group = "caddy"; + User = cfg.user; + Group = cfg.group; Restart = "on-abnormal"; - StartLimitIntervalSec = 14400; - StartLimitBurst = 10; AmbientCapabilities = "cap_net_bind_service"; CapabilityBoundingSet = "cap_net_bind_service"; NoNewPrivileges = true; @@ -99,13 +154,18 @@ in { }; }; - users.users.caddy = { - group = "caddy"; - uid = config.ids.uids.caddy; - home = cfg.dataDir; - createHome = true; + users.users = optionalAttrs (cfg.user == "caddy") { + caddy = { + group = cfg.group; + uid = config.ids.uids.caddy; + home = cfg.dataDir; + createHome = true; + }; + }; + + users.groups = optionalAttrs (cfg.group == "caddy") { + caddy.gid = config.ids.gids.caddy; }; - users.groups.caddy.gid = config.ids.uids.caddy; }; } |