{ config, lib, pkgs, ... }: let cfg = config.syscfg.server; containers = cfg.containers; faviconOverride = { " ~* /favicon\.(ico|png|svg|jpg)$" = { extraConfig = '' add_header Content-Type image/svg+xml; return 200 ''; ''; # proxyPass = "http://127.0.0.1:9000"; }; }; # Function to convert your container config into an NGINX vhost mkVhost = container: { forceSSL = true; # quic = true; # http3 = true; useACMEHost = "${cfg.hostDomain}"; locations = faviconOverride // { "/" = { proxyPass = "http://${container.ip}:${toString container.port}"; proxyWebsockets = true; # Recommended for modern apps }; }; }; in { config = lib.mkIf ( config.syscfg.server.web) { security.acme = { acceptTerms = true; defaults.email = "admin@domain.org"; certs."${cfg.hostDomain}" = { domain = "*.${cfg.hostDomain}"; extraDomainNames = [ "${cfg.hostDomain}" ]; # Adds the root too dnsProvider = "infomaniak"; credentialsFile = config.sops.secrets."INFOMANIAK_API_KEY".path; # File containing your API token (e.g. CLOUDFLARE_DNS_API_TOKEN=...) group = "nginx"; }; }; services.nginx = { enable = true; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedGzipSettings = true; # appendHttpConfig = '' # add_header Alt-Svc 'h3=":443"; ma=86400'; # ''; commonHttpConfig = '' proxy_buffer_size 32k; proxy_buffers 8 16k; proxy_busy_buffers_size 48k; port_in_redirect off; ''; virtualHosts = { "_" = { default = true; forceSSL = true; # quic = true; # http3 = true; useACMEHost = "${cfg.hostDomain}"; locations = { "/" = { extraConfig = '' return 404; ''; }; }; }; "sec.${cfg.hostDomain}" = { forceSSL = true; # quic = true; # http3 = true; useACMEHost = "${cfg.hostDomain}"; locations = { "/" = { extraConfig = '' proxy_set_header X-Original-URL $scheme://$http_host$request_uri; proxy_set_header X-Original-URI $scheme://$http_host$request_uri; auth_request /outpost.goauthentik.io/auth/nginx; error_page 401 = @goauthentik_proxy_signin; auth_request_set $auth_cookie $upstream_http_set_cookie; add_header Set-Cookie $auth_cookie; auth_request_set $authentik_username $upstream_http_x_authentik_username; auth_request_set $authentik_groups $upstream_http_x_authentik_groups; auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements; auth_request_set $authentik_email $upstream_http_x_authentik_email; auth_request_set $authentik_name $upstream_http_x_authentik_name; auth_request_set $authentik_uid $upstream_http_x_authentik_uid; proxy_set_header X-authentik-username $authentik_username; proxy_set_header X-authentik-groups $authentik_groups; proxy_set_header X-authentik-entitlements $authentik_entitlements; proxy_set_header X-authentik-email $authentik_email; proxy_set_header X-authentik-name $authentik_name; proxy_set_header X-authentik-uid $authentik_uid; proxy_pass http://helcel.net ''; }; "/outpost.goauthentik.io" = { proxyPass = "http://${config.syscfg.server.containers.authentik.ip}:${toString config.syscfg.server.containers.authentik.port}/outpost.goauthentik.io"; extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Original-URL $scheme://$http_host$request_uri; proxy_set_header X-Original-URI $scheme://$http_host$request_uri; add_header Set-Cookie $auth_cookie; auth_request_set $auth_cookie $upstream_http_set_cookie; proxy_pass_request_body off; proxy_set_header Content-Length ""; ''; }; }; extraConfig = '' location @goauthentik_proxy_signin { internal; add_header Set-Cookie $auth_cookie; return 302 https://${cfg.containers.authentik.subdomain}.${cfg.hostDomain}/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri; } ''; }; } //lib.mapAttrs' (name: v: lib.nameValuePair "${v.subdomain}.${cfg.hostDomain}" (mkVhost v) ) containers; }; }; }