Some checks failed
		
		
	
	CI / Check, build and cache Nix flake (push) Failing after 6m29s
				
			
		
			
				
	
	
		
			502 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			502 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| { lib, pkgs, config, ... }:
 | |
| let
 | |
|   inherit (builtins) mapAttrs toJSON;
 | |
|   inherit (lib) mkMerge mkDefault genAttrs flatten concatStringsSep;
 | |
|   inherit (lib.my.c) pubDomain home;
 | |
|   inherit (lib.my.c.nginx) proxyHeaders;
 | |
|   inherit (config.networking) domain;
 | |
| 
 | |
|   dualStackListen' = l: map (addr: l // { inherit addr; }) [ "0.0.0.0" "[::]" ];
 | |
|   dualStackListen = ll: flatten (map dualStackListen' ll);
 | |
| 
 | |
|   ssoServer = i: {
 | |
|     extraConfig = ''
 | |
|       include /etc/nginx/includes/sso/server-${i}.conf;
 | |
|     '';
 | |
|   };
 | |
|   ssoLoc = i: {
 | |
|     extraConfig = ''
 | |
|       include /etc/nginx/includes/sso/location-${i}.conf;
 | |
|     '';
 | |
|   };
 | |
| 
 | |
|   mkWellKnown = type: content: pkgs.writeTextFile {
 | |
|     name = "well-known-${type}";
 | |
|     destination = "/${type}";
 | |
|     text = content;
 | |
|   };
 | |
|   wellKnownRoot = pkgs.symlinkJoin {
 | |
|     name = "http-wellknown";
 | |
|     paths = [
 | |
|       # For federation
 | |
|       (mkWellKnown "matrix/server" (toJSON {
 | |
|         "m.server" = "matrix.nul.ie:443";
 | |
|       }))
 | |
|       # For clients
 | |
|       (mkWellKnown "matrix/client" (toJSON {
 | |
|         "m.homeserver".base_url = "https://matrix.nul.ie";
 | |
|       }))
 | |
|     ];
 | |
|   };
 | |
|   wellKnown = {
 | |
|     "/.well-known/" = {
 | |
|       alias = "${wellKnownRoot}/";
 | |
|       extraConfig = ''
 | |
|         autoindex on;
 | |
|         add_header Access-Control-Allow-Origin *;
 | |
|       '';
 | |
|     };
 | |
|     "/.well-known/webfinger".return = "301 https://toot.nul.ie$request_uri";
 | |
|     "/.well-known/nodeinfo".return = "301 https://toot.nul.ie$request_uri";
 | |
|     "/.well-known/host-meta".return = "301 https://toot.nul.ie$request_uri";
 | |
|   };
 | |
| in
 | |
| {
 | |
|   my = {
 | |
|     nginx-sso.includes.instances = {
 | |
|       generic = {};
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   services.nginx.virtualHosts =
 | |
|   let
 | |
|     hosts = {
 | |
|       "_" = {
 | |
|         default = true;
 | |
|         forceSSL = true;
 | |
|         onlySSL = false;
 | |
|         locations = mkMerge [
 | |
|           {
 | |
|             "/".root = pkgs.linkFarm "nginx-root" [
 | |
|               {
 | |
|                 name = "index.html";
 | |
|                 path = ./default.html;
 | |
|               }
 | |
|               {
 | |
|                 name = "cv.pdf";
 | |
|                 path = builtins.fetchurl {
 | |
|                   url = "https://github.com/devplayer0/cvos/releases/download/v0.1.3/bootable.pdf";
 | |
|                   sha256 = "018wh6ps19n7323fi44njzj9yd4wqslc90dykbwfyscv7bgxhlar";
 | |
|                 };
 | |
|               }
 | |
|             ];
 | |
|           }
 | |
|           wellKnown
 | |
|         ];
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "localhost" = {
 | |
|         forceSSL = false;
 | |
|         onlySSL = false;
 | |
|         locations = {
 | |
|           "/status".extraConfig = ''
 | |
|             access_log off;
 | |
|             allow 127.0.0.1;
 | |
|             allow ::1;
 | |
|             deny all;
 | |
| 
 | |
|             vhost_traffic_status_display;
 | |
|             vhost_traffic_status_display_format html;
 | |
|           '';
 | |
|         };
 | |
|       };
 | |
| 
 | |
|       "sso.${pubDomain}" = {
 | |
|         locations."/".proxyPass = config.my.nginx-sso.includes.endpoint;
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "netdata-colony.${pubDomain}" =
 | |
|       let
 | |
|         hosts = [
 | |
|           "vm"
 | |
|           "fw" "ctr" "oci"
 | |
|           "http" "jackflix-ctr" "chatterbox-ctr" "colony-psql-ctr"
 | |
|         ];
 | |
|         matchHosts = concatStringsSep "|" hosts;
 | |
|       in
 | |
|       mkMerge [
 | |
|         {
 | |
|           locations = {
 | |
|             "= /".return = "301 https://$host/vm/";
 | |
|             "~ /(?<behost>${matchHosts})$".return = "301 https://$host/$behost/";
 | |
|             "~ /(?<behost>${matchHosts})/(?<ndpath>.*)" = mkMerge [
 | |
|               {
 | |
|                 proxyPass = "http://$behost.${domain}:19999/$ndpath$is_args$args";
 | |
|                 extraConfig = ''
 | |
|                   proxy_pass_request_headers on;
 | |
|                   ${proxyHeaders}
 | |
|                   proxy_set_header Connection "keep-alive";
 | |
|                   proxy_store off;
 | |
| 
 | |
|                   gzip on;
 | |
|                   gzip_proxied any;
 | |
|                   gzip_types *;
 | |
|                 '';
 | |
|               }
 | |
|               (ssoLoc "generic")
 | |
|             ];
 | |
|           };
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
| 
 | |
|       "pass.${pubDomain}" =
 | |
|       let
 | |
|         upstream = "http://vaultwarden-ctr.${domain}:8080";
 | |
|       in
 | |
|       {
 | |
|         locations = {
 | |
|           "/".proxyPass = upstream;
 | |
|           "/notifications/hub" = {
 | |
|             proxyPass = upstream;
 | |
|             proxyWebsockets = true;
 | |
|             extraConfig = proxyHeaders;
 | |
|           };
 | |
|           "/notifications/hub/negotiate".proxyPass = upstream;
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "matrix.nul.ie" = {
 | |
|         listen = dualStackListen [
 | |
|           {
 | |
|             port = 443;
 | |
|             ssl = true;
 | |
|           }
 | |
|           {
 | |
|             # Matrix federation
 | |
|             port = 8448;
 | |
|             ssl = true;
 | |
|             extraParameters = [ "default_server" ];
 | |
|           }
 | |
|         ];
 | |
|         locations = mkMerge [
 | |
|           {
 | |
|             "/".proxyPass = "http://chatterbox-ctr.${domain}:8008";
 | |
|             "= /".return = "301 https://element.${pubDomain}";
 | |
|           }
 | |
|           wellKnown
 | |
|         ];
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "element.${pubDomain}" =
 | |
|       let
 | |
|         headers = ''
 | |
|           # TODO: why are these here?
 | |
|           #add_header X-Frame-Options SAMEORIGIN;
 | |
|           #add_header X-Content-Type-Options nosniff;
 | |
|           #add_header X-XSS-Protection "1; mode=block";
 | |
|           # This seems to break file downloads...
 | |
|           #add_header Content-Security-Policy "frame-ancestors 'none'";
 | |
|         '';
 | |
|       in
 | |
|       {
 | |
|         extraConfig = ''
 | |
|           ${headers}
 | |
|         '';
 | |
|         root = pkgs.element-web.override {
 | |
|           # Currently it seems like single quotes aren't escaped like they should be...
 | |
|           conf = {
 | |
|             brand = "/dev/player0 Matrix";
 | |
|             show_labs_settings = true;
 | |
|             default_country_code = "IE";
 | |
|             disable_guests = true;
 | |
|             default_server_config = {
 | |
|               "m.homeserver" = {
 | |
|                 base_url = "https://matrix.nul.ie";
 | |
|                 server_name = "nul.ie";
 | |
|               };
 | |
|             };
 | |
|             room_directory.servers = [
 | |
|               "nul.ie"
 | |
|               "matrix.org"
 | |
|             ];
 | |
|           };
 | |
|         };
 | |
|         locations = mkMerge [
 | |
|           { }
 | |
|           (genAttrs [ "= /index.html" "= /version" "/config" ] (_: {
 | |
|             extraConfig = ''
 | |
|               # Gotta duplicate the headers...
 | |
|               # https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md
 | |
|               ${headers}
 | |
|               add_header Cache-Control "no-cache";
 | |
|             '';
 | |
|           }))
 | |
|         ];
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "torrents.${pubDomain}" = mkMerge [
 | |
|         {
 | |
|           locations."/" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://jackflix-ctr.${domain}:9091";
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
| 
 | |
|       "jackett.${pubDomain}" = mkMerge [
 | |
|         {
 | |
|           locations."/" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://jackflix-ctr.${domain}:9117";
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
|       "radarr.${pubDomain}" = mkMerge [
 | |
|         {
 | |
|           locations."/" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://jackflix-ctr.${domain}:7878";
 | |
|               proxyWebsockets = true;
 | |
|               extraConfig = proxyHeaders;
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
|       "sonarr.${pubDomain}" = mkMerge [
 | |
|         {
 | |
|           locations."/" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://jackflix-ctr.${domain}:8989";
 | |
|               proxyWebsockets = true;
 | |
|               extraConfig = proxyHeaders;
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
|       "gib.${pubDomain}" = {
 | |
|         locations."/".proxyPass = "http://jackflix-ctr.${domain}:5055";
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "jackflix.${pubDomain}" =
 | |
|       let
 | |
|         upstream = "http://jackflix-ctr.${domain}:8096";
 | |
|       in
 | |
|       {
 | |
|         extraConfig = ''
 | |
|           add_header X-Frame-Options "SAMEORIGIN";
 | |
|           add_header X-XSS-Protection "1; mode=block";
 | |
|           add_header X-Content-Type-Options "nosniff";
 | |
|         '';
 | |
|         locations = {
 | |
|           "/".proxyPass = upstream;
 | |
| 
 | |
|           "= /".return = "302 https://$host/web/";
 | |
|           "= /web/".proxyPass = "${upstream}/web/index.html";
 | |
| 
 | |
|           "/socket" = {
 | |
|             proxyPass = upstream;
 | |
|             proxyWebsockets = true;
 | |
|             extraConfig = proxyHeaders;
 | |
|           };
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "toot.nul.ie" = {
 | |
|         locations."/" = {
 | |
|           proxyPass = "http://toot-ctr.${domain}:80";
 | |
|           proxyWebsockets = true;
 | |
|           extraConfig = proxyHeaders;
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "share.${pubDomain}" = {
 | |
|         locations."/" = {
 | |
|           proxyPass = "http://object-ctr.${domain}:9090";
 | |
|           proxyWebsockets = true;
 | |
|           extraConfig = proxyHeaders;
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "stuff.${pubDomain}" = {
 | |
|         locations."/" = {
 | |
|           basicAuthFile = config.age.secrets."middleman/htpasswd".path;
 | |
|           root = "/mnt/media/stuff";
 | |
|           extraConfig = ''
 | |
|             fancyindex on;
 | |
|             fancyindex_show_dotfiles on;
 | |
|           '';
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "public.${pubDomain}" = {
 | |
|         serverAliases = [ "p.${pubDomain}" ];
 | |
|         locations."/" = {
 | |
|           root = "/mnt/media/public";
 | |
|           extraConfig = ''
 | |
|             fancyindex on;
 | |
|             fancyindex_show_dotfiles on;
 | |
|           '';
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "mc-map.${pubDomain}" = {
 | |
|         locations."/".proxyPass = "http://simpcraft-oci.${domain}:8100";
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "mc-rail.${pubDomain}" = {
 | |
|         locations."/".proxyPass = "http://simpcraft-oci.${domain}:3876";
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "librespeed.${domain}" = {
 | |
|         locations."/".proxyPass = "http://localhost:8989";
 | |
|       };
 | |
|       "speed.${pubDomain}" = {
 | |
|         locations."/".proxyPass = "http://localhost:8989";
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "md.${pubDomain}" = {
 | |
|         locations."/" = {
 | |
|           proxyPass = "http://object-ctr.${domain}:3000";
 | |
|           proxyWebsockets = true;
 | |
|           extraConfig = proxyHeaders;
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "pb.${pubDomain}" = {
 | |
|         locations."/".proxyPass = "http://object-ctr.${domain}:8088";
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "photos.${pubDomain}" = {
 | |
|         locations."/" = {
 | |
|           proxyPass = "http://jackflix-ctr.${domain}:2342";
 | |
|           proxyWebsockets = true;
 | |
|           extraConfig = proxyHeaders;
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "pront.${pubDomain}" = mkMerge [
 | |
|         {
 | |
|           locations."/" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://stream-hi.${home.domain}:5000";
 | |
|               proxyWebsockets = true;
 | |
|               extraConfig = proxyHeaders;
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           locations."~* ^/webcam/(.*)" = mkMerge [
 | |
|             {
 | |
|               proxyPass = "http://stream-hi.${home.domain}:5050/$1$is_args$args";
 | |
|               extraConfig = proxyHeaders;
 | |
|             }
 | |
|             (ssoLoc "generic")
 | |
|           ];
 | |
|           useACMEHost = pubDomain;
 | |
|         }
 | |
|         (ssoServer "generic")
 | |
|       ];
 | |
|     };
 | |
| 
 | |
|     minio =
 | |
|     let
 | |
|       host = "object-ctr.${domain}";
 | |
|       s3Upstream = "http://${host}:9000";
 | |
|       extraConfig = ''
 | |
|         chunked_transfer_encoding off;
 | |
|         ignore_invalid_headers off;
 | |
|       '';
 | |
| 
 | |
|       nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar.*|serve\/.+)$'';
 | |
|       nixCacheHeaders = ''
 | |
|         add_header Cache-Control $nix_cache_control;
 | |
|         add_header Expires $nix_expires;
 | |
| 
 | |
|         brotli on;
 | |
|         brotli_types application/x-nix-archive;
 | |
|       '';
 | |
|     in
 | |
|     {
 | |
|       "minio.${pubDomain}" = {
 | |
|         inherit extraConfig;
 | |
|         locations = {
 | |
|           "/" = {
 | |
|             proxyPass = "http://${host}:9001";
 | |
|           };
 | |
|           "/ws" = {
 | |
|             proxyPass = "http://${host}:9001";
 | |
|             proxyWebsockets = true;
 | |
|             extraConfig = proxyHeaders;
 | |
|           };
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|       "s3.${pubDomain}" = {
 | |
|         serverAliases = [ "*.s3.${pubDomain}" ];
 | |
|         inherit extraConfig;
 | |
|         locations = {
 | |
|           "/".proxyPass = s3Upstream;
 | |
|           "/gitea/packages/" = {
 | |
|             proxyPass = s3Upstream;
 | |
|             # HACK: Docker images need the MIME type to be correct for the manifest but Gitea
 | |
|             # doesn't tell S3... By hiding the header we can use add_header to set Content-Type
 | |
|             # (normally can't be set directly)
 | |
|             extraConfig = ''
 | |
|               proxy_hide_header Content-Type;
 | |
|               add_header Content-Type $upstream_http_content_type always;
 | |
|               if ($args ~ "response-content-disposition=.+filename%3D%22manifest\.json%22") {
 | |
|                 add_header Content-Type "application/vnd.docker.distribution.manifest.v2+json";
 | |
|               }
 | |
|             '';
 | |
|           };
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
| 
 | |
|       "nix-cache.${pubDomain}" = {
 | |
|         locations = {
 | |
|           "/" = {
 | |
|             proxyPass = "http://${host}:5000";
 | |
|           };
 | |
|           "~ ${nixCacheableRegex}" = {
 | |
|             proxyPass = "http://${host}:5000";
 | |
|             extraConfig = nixCacheHeaders;
 | |
|           };
 | |
|         };
 | |
|         useACMEHost = pubDomain;
 | |
|       };
 | |
|     };
 | |
| 
 | |
|     defaultsFor = mapAttrs (n: _: {
 | |
|       onlySSL = mkDefault true;
 | |
|       useACMEHost = mkDefault "${domain}";
 | |
|       kTLS = mkDefault true;
 | |
|       http2 = mkDefault true;
 | |
|     });
 | |
|   in
 | |
|   mkMerge [
 | |
|     hosts
 | |
|     (defaultsFor hosts)
 | |
| 
 | |
|     minio
 | |
|     (defaultsFor minio)
 | |
|   ];
 | |
| }
 |