1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-24 10:10:37 +03:00

nixos/caddy: add support for reload

This commit is contained in:
Sylvain Fankhauser 2023-02-21 17:21:38 +01:00
parent d9c0d0ddfb
commit 1f0ac736b4
No known key found for this signature in database
GPG key ID: 4228AB9EC0612ADA
3 changed files with 48 additions and 8 deletions

View file

@ -41,6 +41,14 @@ let
in
"${if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform then Caddyfile-formatted else Caddyfile}/Caddyfile";
adminDisabled = lib.fileContents (pkgs.runCommand "caddy-config-adapted" {} ''
${cfg.package}/bin/caddy adapt --config ${configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"} | ${pkgs.jq}/bin/jq .admin.disabled > $out
'') == "true";
etcConfigFile = "caddy/caddy_config";
configPath = "/etc/${etcConfigFile}";
acmeHosts = unique (catAttrs "useACMEHost" acmeVHosts);
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
@ -155,11 +163,16 @@ in
description = lib.mdDoc ''
Override the configuration file used by Caddy. By default,
NixOS generates one automatically.
The configuration file is exposed at {file}`${configPath}`.
'';
};
adapter = mkOption {
default = null;
default = if (builtins.baseNameOf cfg.configFile) == "Caddyfile" then "caddyfile" else null;
defaultText = literalExpression ''
if (builtins.baseNameOf cfg.configFile) == "Caddyfile" then "caddyfile" else null
'';
example = literalExpression "nginx";
type = with types; nullOr str;
description = lib.mdDoc ''
@ -275,6 +288,21 @@ in
'';
};
enableReload = mkOption {
default = true;
type = types.bool;
description = lib.mdDoc ''
Reload Caddy instead of restarting it when configuration file changes.
Note that enabling this option requires the [admin API](https://caddyserver.com/docs/caddyfile/options#admin)
to not be turned off.
If you enable this option, consider setting [`grace_period`](https://caddyserver.com/docs/caddyfile/options#grace-period)
to a non-infinite value in {option}`services.caddy.globalConfig`
to prevent Caddy waiting for active connections to finish,
which could delay the reload essentially indefinitely.
'';
};
};
# implementation
@ -284,6 +312,9 @@ in
{ assertion = cfg.configFile == configFile -> cfg.adapter == "caddyfile" || cfg.adapter == null;
message = "To specify an adapter other than 'caddyfile' please provide your own configuration via `services.caddy.configFile`";
}
{ assertion = cfg.enableReload -> !adminDisabled;
message = "You need to remove `admin off` from your Caddy configuration in order to use `services.caddy.enableReload`";
}
] ++ map (name: mkCertOwnershipAssertion {
inherit (cfg) group user;
cert = config.security.acme.certs.${name};
@ -311,13 +342,16 @@ in
wantedBy = [ "multi-user.target" ];
startLimitIntervalSec = 14400;
startLimitBurst = 10;
reloadTriggers = optional cfg.enableReload cfg.configFile;
serviceConfig = {
serviceConfig = let
runOptions = ''--config ${configPath} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"}'';
in {
# https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
# If the empty string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect.
ExecStart = [ "" ''${cfg.package}/bin/caddy run --config ${cfg.configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"} ${optionalString cfg.resume "--resume"}'' ];
ExecReload = [ "" ''${cfg.package}/bin/caddy reload --config ${cfg.configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"} --force'' ];
ExecStartPre = ''${cfg.package}/bin/caddy validate --config ${cfg.configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"}'';
ExecStart = [ "" ''${cfg.package}/bin/caddy run ${runOptions} ${optionalString cfg.resume "--resume"}'' ];
# Validating the configuration before applying it ensures well get a proper error that will be reported when switching to the configuration
ExecReload = [ "" ''${cfg.package}/bin/caddy reload ${runOptions} --force'' ];
User = cfg.user;
Group = cfg.group;
ReadWriteDirectories = cfg.dataDir;
@ -353,5 +387,6 @@ in
in
listToAttrs certCfg;
environment.etc.${etcConfigFile}.source = cfg.configFile;
};
}