{ config, pkgs, inputs, lib, ... }: let # String = simple site, Attrset = custom site. sites = { "analytics.figtree.dev" = "http://192.168.80.1:3300"; "figtree.dev" = "http://192.168.1.63:8080"; "files.figtree.dev" = "http://192.168.80.4:8080"; "git.figtree.dev" = "http://192.168.80.2:3000"; "nc.figtree.dev" = "http://192.168.1.62:11000"; "paperless.figtree.dev" = "http://192.168.1.63:8010"; "photos.figtree.dev" = "http://192.168.80.1:2283"; "shiori.figtree.dev" = "http://192.168.80.4:8234"; "tasks.figtree.dev" = "http://192.168.80.7:3456"; "www.figtree.dev" = "http://192.168.1.63:8080"; "ha.figtree.dev" = "http://192.168.1.50:8123"; # "budget.figtree.dev" = "http://192.168.80.1:5006"; # .box domains now automatically get "tls internal" "home.box" = "http://192.168.1.63:3000"; "budget.box" = "http://192.168.80.1:5006"; "torrent.box" = "http://192.168.1.65:8080"; "books.box" = "http://192.168.80.4:8010"; }; # Normalize sites: # 1. Turn strings into { backend = "..."; }. # 2. Automatically prepend `tls internal` for any domain ending in .box. normalizedSites = lib.mapAttrs (domain: siteConfig: let # Ensure siteConfig is an attrset. baseConfig = if lib.isString siteConfig then { backend = siteConfig; } else siteConfig; # Check if it's a .box domain. isBoxDomain = lib.hasSuffix ".box" domain; in if isBoxDomain then baseConfig // { extraBefore = '' tls internal ${lib.optionalString (baseConfig ? extraBefore) baseConfig.extraBefore} ''; } else baseConfig ) sites; # Render each vhost from its config. mkVHost = cfg: { extraConfig = '' ${lib.optionalString (cfg ? extraBefore) cfg.extraBefore} reverse_proxy ${cfg.backend} ${lib.optionalString (cfg ? extra) cfg.extra} ''; }; in { services.caddy = { enable = true; virtualHosts = lib.mapAttrs (_: cfg: mkVHost cfg) normalizedSites; }; }