mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-11 12:15:34 +03:00
nixos/caddy: add support for reload
This commit is contained in:
parent
d9c0d0ddfb
commit
1f0ac736b4
3 changed files with 48 additions and 8 deletions
|
@ -64,6 +64,8 @@
|
||||||
|
|
||||||
- `spamassassin` no longer supports the `Hashcash` module. The module needs to be removed from the `loadplugin` list if it was copied over from the default `initPreConf` option.
|
- `spamassassin` no longer supports the `Hashcash` module. The module needs to be removed from the `loadplugin` list if it was copied over from the default `initPreConf` option.
|
||||||
|
|
||||||
|
- The Caddy module gained a new option named `services.caddy.enableReload` which is enabled by default. It allows reloading the service instead of restarting it, if only a config file has changed. This option must be disabled if you have turned off the [Caddy admin API](https://caddyserver.com/docs/caddyfile/options#admin). If you keep this option enabled, you should consider setting [`grace_period`](https://caddyserver.com/docs/caddyfile/options#grace-period) to a non-infinite value to prevent Caddy from delaying the reload indefinitely.
|
||||||
|
|
||||||
## Other Notable Changes {#sec-release-23.11-notable-changes}
|
## Other Notable Changes {#sec-release-23.11-notable-changes}
|
||||||
|
|
||||||
- The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration.
|
- The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration.
|
||||||
|
|
|
@ -41,6 +41,14 @@ let
|
||||||
in
|
in
|
||||||
"${if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform then Caddyfile-formatted else Caddyfile}/Caddyfile";
|
"${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);
|
acmeHosts = unique (catAttrs "useACMEHost" acmeVHosts);
|
||||||
|
|
||||||
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
|
mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix;
|
||||||
|
@ -155,11 +163,16 @@ in
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Override the configuration file used by Caddy. By default,
|
Override the configuration file used by Caddy. By default,
|
||||||
NixOS generates one automatically.
|
NixOS generates one automatically.
|
||||||
|
|
||||||
|
The configuration file is exposed at {file}`${configPath}`.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
adapter = mkOption {
|
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";
|
example = literalExpression "nginx";
|
||||||
type = with types; nullOr str;
|
type = with types; nullOr str;
|
||||||
description = lib.mdDoc ''
|
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
|
# implementation
|
||||||
|
@ -284,6 +312,9 @@ in
|
||||||
{ assertion = cfg.configFile == configFile -> cfg.adapter == "caddyfile" || cfg.adapter == null;
|
{ 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`";
|
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 {
|
] ++ map (name: mkCertOwnershipAssertion {
|
||||||
inherit (cfg) group user;
|
inherit (cfg) group user;
|
||||||
cert = config.security.acme.certs.${name};
|
cert = config.security.acme.certs.${name};
|
||||||
|
@ -311,13 +342,16 @@ in
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
startLimitIntervalSec = 14400;
|
startLimitIntervalSec = 14400;
|
||||||
startLimitBurst = 10;
|
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=
|
# 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.
|
# 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"}'' ];
|
ExecStart = [ "" ''${cfg.package}/bin/caddy run ${runOptions} ${optionalString cfg.resume "--resume"}'' ];
|
||||||
ExecReload = [ "" ''${cfg.package}/bin/caddy reload --config ${cfg.configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"} --force'' ];
|
# Validating the configuration before applying it ensures we’ll get a proper error that will be reported when switching to the configuration
|
||||||
ExecStartPre = ''${cfg.package}/bin/caddy validate --config ${cfg.configFile} ${optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}"}'';
|
ExecReload = [ "" ''${cfg.package}/bin/caddy reload ${runOptions} --force'' ];
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
ReadWriteDirectories = cfg.dataDir;
|
ReadWriteDirectories = cfg.dataDir;
|
||||||
|
@ -353,5 +387,6 @@ in
|
||||||
in
|
in
|
||||||
listToAttrs certCfg;
|
listToAttrs certCfg;
|
||||||
|
|
||||||
|
environment.etc.${etcConfigFile}.source = cfg.configFile;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
services.caddy.enableReload = true;
|
||||||
|
|
||||||
specialisation.etag.configuration = {
|
specialisation.etag.configuration = {
|
||||||
services.caddy.extraConfig = lib.mkForce ''
|
services.caddy.extraConfig = lib.mkForce ''
|
||||||
|
@ -54,9 +55,9 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
|
|
||||||
testScript = { nodes, ... }:
|
testScript = { nodes, ... }:
|
||||||
let
|
let
|
||||||
etagSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/etag";
|
etagSystem = "${nodes.webserver.system.build.toplevel}/specialisation/etag";
|
||||||
justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/config-reload";
|
justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/config-reload";
|
||||||
multipleConfigs = "${nodes.webserver.config.system.build.toplevel}/specialisation/multiple-configs";
|
multipleConfigs = "${nodes.webserver.system.build.toplevel}/specialisation/multiple-configs";
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
url = "http://localhost/example.html"
|
url = "http://localhost/example.html"
|
||||||
|
@ -96,6 +97,8 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
"${justReloadSystem}/bin/switch-to-configuration test >&2"
|
"${justReloadSystem}/bin/switch-to-configuration test >&2"
|
||||||
)
|
)
|
||||||
webserver.wait_for_open_port(8080)
|
webserver.wait_for_open_port(8080)
|
||||||
|
webserver.fail("journalctl -u caddy | grep -q -i stopped")
|
||||||
|
webserver.succeed("journalctl -u caddy | grep -q -i reloaded")
|
||||||
|
|
||||||
with subtest("multiple configs are correctly merged"):
|
with subtest("multiple configs are correctly merged"):
|
||||||
webserver.succeed(
|
webserver.succeed(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue