{ config, pkgs, lib, ... }: let network = import ../data/network.nix; virtualHostFn = name: service: let domain = if service ? domainOverride then service.domainOverride else "${name}.${network.local_domain}"; locationList = if service.reverse_proxy ? endpoints then service.reverse_proxy.endpoints else ["/"]; locationsData = builtins.listToAttrs (map (endpointName: { name = endpointName; value = { proxyPass = "http://127.0.0.1:${builtins.toString service.reverse_proxy.port}/"; proxyWebsockets = true; }; }) locationList); serverAlias = lib.optionalAttrs (service.reverse_proxy ? aliases) { serverAliases = map (alias: "${alias}.${domain}") service.reverse_proxy.aliases; }; myExtraConfig = if service.reverse_proxy ? extraConfig then service.reverse_proxy.extraConfig else {}; listenConfig = if service.reverse_proxy ? listen then service.reverse_proxy.listen else if service.reverse_proxy ? ssl && service.reverse_proxy.ssl then [ {port = 80;} {port = 443; ssl=true;} ] else [ {port = 80;} ]; sslConfig = if service.reverse_proxy ? ssl && service.reverse_proxy.ssl then { enableACME = true; forceSSL = true; } else {}; externConnections = if service.reverse_proxy ? allowExternConnections && service.reverse_proxy.allowExternConnections then { extraConfig = '' allow all; ''; } else {}; in { serverName = "${domain}"; listen = map (obj: ({ addr = if obj ? addr then obj.addr else "0.0.0.0"; port = obj.port; } // (if obj ? ssl then {ssl = obj.ssl;} else {}))) listenConfig; locations = locationsData; extraConfig = '' allow ${network.network.subnet}; deny all; ''; } // serverAlias // sslConfig // externConnections // myExtraConfig; rproxyServices = builtins.mapAttrs (virtualHostFn) network.reverse_proxy; serviceNamesMessage = builtins.toString (builtins.attrNames network.reverse_proxy); fallback = { serverName = "_"; listen = [ {addr = "0.0.0.0"; port = 80;}]; locations."/" = { return = "404"; extraConfig = '' add_header Content-Type text/plain; ''; }; extraConfig = '' return 404 "This domain is not configured. Available services: ${serviceNamesMessage}"; ''; }; in { services.nginx = { enable = true; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; virtualHosts = rproxyServices // {fallback = fallback;}; }; networking.firewall.allowedTCPPorts = network.usedPorts; security.acme = { acceptTerms = true; defaults.email = "katharina.heidenreich02@gmail.com"; }; }