{lib, pkgs, config, ...}: /* taken from https://github.com/jdheyburn/nixos-configs no license */ with lib; let cfg = config.modules.caddy; caddyMetricsPort = 2019; # Generate Caddyfile content from the proxy configuration generateCaddyfile = proxies: let proxyEntries = mapAttrsToList (domain: upstreams: let upstreamList = if isList upstreams then upstreams else [upstreams]; upstreamStr = concatStringsSep " " upstreamList; in '' ${domain} { reverse_proxy ${upstreamStr} # Optional: Add some common headers for better proxying header_up Host {upstream_hostport} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } '') proxies; in concatStringsSep "\n\n" proxyEntries; in { options = { modules = { caddy = { enable = mkEnableOption "Deploy Caddy"; reverseProxies = mkOption { type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; description = "Attribute set of domain to upstream mappings for reverse proxying. Upstreams can be a single string or a list of strings for load balancing."; example = { "notes.nekomimi.pet" = "valefar:3009"; "git.nekomimi.pet" = ["morax:3000" "valefar:3000"]; # Load balance between multiple upstreams "api.nekomimi.pet" = ["server1:8080" "server2:8080" "server3:8080"]; }; }; extraConfig = mkOption { type = types.lines; default = ""; description = "Extra Caddyfile configuration to append"; }; email = mkOption { type = types.nullOr types.str; default = null; description = "Email address for ACME certificate registration"; }; }; }; }; config = mkIf cfg.enable { # Allow network access when building # https://mdleom.com/blog/2021/12/27/caddy-plugins-nixos/#xcaddy #nix.settings.sandbox = false; networking.firewall.allowedTCPPorts = [ 80 443 caddyMetricsPort ]; services.caddy = { enable = true; /*package = pkgs.caddy.withPlugins { plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1"]; hash = "sha256-1niaf801sijvjrqvw998y8x7b43a0g162h3ry530qwl8lrgkapii"; };*/ extraConfig = '' ${optionalString (cfg.email != null) '' { email ${cfg.email} } ''} ${generateCaddyfile cfg.reverseProxies} ${cfg.extraConfig} ''; }; systemd.services.caddy = { serviceConfig = { AmbientCapabilities = "cap_net_bind_service"; CapabilityBoundingSet = "cap_net_bind_service"; TimeoutStartSec = "5m"; }; }; }; }