{ commonHttpConfig, enableACME, extraConfig, forceSSL, ... }: Service "Nginx: HTTP-Server" { configuration = { config, core, network, store, web, ... }: let inherit(core) derivation path set string type; inherit(network) allowLegacyTLS domain hostName ips tcp; inherit(store) write; inherit(tcp.ports) exporters; websites = let importWebsite = value: type.matchPrimitiveOrPanic value { lambda = value { inherit core hostName store web; }; null = {}; path = importWebsite (path.import value); set = value; }; in importWebsite (path.import ./hosts).${hostName}; allowedIPs = string.concatMappedWith (ip: "allow ${ip};") "\n" ips; locations = let extraConfig = '' ${allowedIPs} deny all; ''; in { "/metrics/nginx" = { inherit extraConfig; proxyPass = "http://localhost:${string exporters.nginx}/metrics"; }; "/metrics/node" = { inherit extraConfig; proxyPass = "http://localhost:${string exporters.node}/metrics"; }; }; mapLocation = domain: location: { index ? "index.html", root, tryFiles ? "$uri $uri.html $uri.txt $uri.asc /index.html", ... }: let foo = string.replace' { "\t" = "_"; "\n" = "_"; "\r" = "_"; " " = "_"; "@" = "-at-"; "/" = "-"; }; directory = write.directory (foo (if location == "/" then domain else "${domain}${location}")) ( set.map ( fileName: page: path.toFile (foo fileName) "${page}" ) root ); in { inherit index tryFiles; root = "${directory}"; }; sslProtocols = if allowLegacyTLS then "TLSv1.2 TLSv1.3" else "TLSv1.3"; in { nginx = { inherit commonHttpConfig sslProtocols; enable = true; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; statusPage = true; virtualHosts = set.mapNamesAndValues ( subdomain: locations': let fqdn = if subdomain != "" then "${subdomain}.${domain}" else domain; in { name = fqdn; value = { inherit enableACME extraConfig forceSSL; locations = locations // (set.map (mapLocation fqdn) locations'); }; } ) websites; }; }; }