{ config, lib, pkgs, ... }: let cfg = config.services.caddy; in { options.services.caddy = { enable = lib.mkEnableOption "Caddy web server (for local development)"; package = lib.mkPackageOption pkgs "caddy" { }; configFile = lib.mkOption { type = lib.types.path; description = '' Path to a Caddyfile configuration file. ''; }; adapter = lib.mkOption { type = with lib.types; nullOr str; default = "caddyfile"; description = '' Name of the config adapter to use. See for the full list. If `null` is specified, the `--adapter` argument is omitted when starting or restarting Caddy. Notably, this allows specification of a configuration file in Caddy's native JSON format, as long as the filename does not start with `Caddyfile` (in which case the `caddyfile` adapter is implicitly enabled). See for details. ''; }; watch = lib.mkOption { type = lib.types.bool; default = false; description = '' Automatically reload the config file, when changed. ''; }; }; config = let args = [ "run" "--config" "${cfg.configFile}" ] ++ lib.optionals (cfg.adapter != null) [ "--adapter" cfg.adapter ] ++ lib.optional cfg.watch "--watch"; in lib.mkIf cfg.enable { home.packages = [ cfg.package ]; launchd.agents.caddy = { enable = true; config = { ProgramArguments = [ (lib.getExe cfg.package) ] ++ args; RunAtLoad = true; }; }; # untested systemd.user.services.caddy = { unitConfig = { wantedBy = [ "default.target" ]; }; serviceConfig = { ExecStart = "${lib.getExe cfg.package} ${lib.escapeShellArgs args}"; }; }; }; }