summary refs log tree commit diff
path: root/nixos/modules/services/web-servers
diff options
context:
space:
mode:
authorSylvain Fankhauser <sephi@fhtagn.top>2023-02-21 17:21:38 +0100
committerSylvain Fankhauser <sephi@fhtagn.top>2023-07-04 11:25:05 +0200
commit1f0ac736b48dbeaed1b3da975d13246b4d3a886c (patch)
treef9298e9c9c766d2c3965d3f420369d3f07fc77a7 /nixos/modules/services/web-servers
parentd9c0d0ddfb3dac5bd5e1e564f48c87c86d1def97 (diff)
downloadnixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar.gz
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar.bz2
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar.lz
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar.xz
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.tar.zst
nixpkgs-1f0ac736b48dbeaed1b3da975d13246b4d3a886c.zip
nixos/caddy: add support for reload
Diffstat (limited to 'nixos/modules/services/web-servers')
-rw-r--r--nixos/modules/services/web-servers/caddy/default.nix45
1 files changed, 40 insertions, 5 deletions
diff --git a/nixos/modules/services/web-servers/caddy/default.nix b/nixos/modules/services/web-servers/caddy/default.nix
index 70715a23725..1056b9525ac 100644
--- a/nixos/modules/services/web-servers/caddy/default.nix
+++ b/nixos/modules/services/web-servers/caddy/default.nix
@@ -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 we’ll 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;
   };
 }