From a877d40892f570a9bc0f8473a5d2dcd0189fecbd Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 17 Aug 2026 21:18:09 +0300 Subject: [PATCH 1/5] test production domain configuration --- checks/rabbi-gerzi-domains.nix | 77 ++++++++++++++++++++++++++++++++++ flake.nix | 6 +++ 2 files changed, 83 insertions(+) create mode 100644 checks/rabbi-gerzi-domains.nix diff --git a/checks/rabbi-gerzi-domains.nix b/checks/rabbi-gerzi-domains.nix new file mode 100644 index 0000000..65ab3fc --- /dev/null +++ b/checks/rabbi-gerzi-domains.nix @@ -0,0 +1,77 @@ +{ + config, + lib, + pkgs, +}: + +let + frontendConfig = config.services.rabbi-gerzi.frontend; + backendConfig = config.services.rabbi-gerzi.backend; + frontendVirtualHost = + config.services.nginx.virtualHosts.${frontendConfig.hostName}; + backendVirtualHost = + config.services.nginx.virtualHosts.${backendConfig.hostName}; + redirectVirtualHost = lib.attrByPath [ "www.rabbigerzi.com" ] { } + config.services.nginx.virtualHosts; + + assertions = [ + { + assertion = frontendConfig.hostName == "rabbigerzi.com"; + message = "Rabbi Gerzi frontend does not use the production domain"; + } + { + assertion = frontendConfig.apiBaseUrl == "https://api.rabbigerzi.com"; + message = "Rabbi Gerzi frontend does not use the production API"; + } + { + assertion = backendConfig.hostName == "api.rabbigerzi.com"; + message = "Rabbi Gerzi backend does not use the production API domain"; + } + { + assertion = backendConfig.corsAllowedOrigins == [ + "https://rabbigerzi.com" + "https://rabbigerzi.yisroelbaum.com" + ]; + message = "Rabbi Gerzi CORS origins do not cover production and staging"; + } + { + assertion = builtins.elem "rabbigerzi.yisroelbaum.com" + frontendVirtualHost.serverAliases; + message = "Rabbi Gerzi frontend staging alias is missing"; + } + { + assertion = builtins.elem "rabbigerziapi.yisroelbaum.com" + backendVirtualHost.serverAliases; + message = "Rabbi Gerzi backend staging alias is missing"; + } + { + assertion = redirectVirtualHost.globalRedirect or null + == "rabbigerzi.com"; + message = "Rabbi Gerzi www host does not redirect to the apex"; + } + { + assertion = redirectVirtualHost.forceSSL or false; + message = "Rabbi Gerzi www redirect does not force HTTPS"; + } + { + assertion = redirectVirtualHost.enableACME or false; + message = "Rabbi Gerzi www redirect does not enable ACME"; + } + ]; + + failedAssertions = lib.filter (assertion: !assertion.assertion) assertions; +in +pkgs.runCommand "rabbi-gerzi-production-domains" + { + failures = lib.concatMapStringsSep "\n" + (assertion: assertion.message) failedAssertions; + preferLocalBuild = true; + } + '' + if [ -n "$failures" ]; then + printf '%s\n' "$failures" >&2 + exit 1 + fi + + touch $out + '' diff --git a/flake.nix b/flake.nix index 1c9a84d..0506c80 100644 --- a/flake.nix +++ b/flake.nix @@ -59,6 +59,12 @@ } ]; }; + checks."${system}".rabbi-gerzi-domains = + import ./checks/rabbi-gerzi-domains.nix { + config = self.nixosConfigurations.nixos.config; + inherit (nixpkgs) lib; + pkgs = nixpkgs.legacyPackages.${system}; + }; devShells."${system}".default = let pkgs = import nixpkgs { inherit system; }; From 6d328b558fbbd5b61b24ddc0356c97702cd22991 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 17 Aug 2026 21:19:04 +0300 Subject: [PATCH 2/5] format domain configuration check --- checks/rabbi-gerzi-domains.nix | 32 ++++++++++++++------------------ flake.nix | 11 +++++------ 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/checks/rabbi-gerzi-domains.nix b/checks/rabbi-gerzi-domains.nix index 65ab3fc..a421860 100644 --- a/checks/rabbi-gerzi-domains.nix +++ b/checks/rabbi-gerzi-domains.nix @@ -7,12 +7,11 @@ let frontendConfig = config.services.rabbi-gerzi.frontend; backendConfig = config.services.rabbi-gerzi.backend; - frontendVirtualHost = - config.services.nginx.virtualHosts.${frontendConfig.hostName}; - backendVirtualHost = - config.services.nginx.virtualHosts.${backendConfig.hostName}; - redirectVirtualHost = lib.attrByPath [ "www.rabbigerzi.com" ] { } - config.services.nginx.virtualHosts; + frontendVirtualHost = config.services.nginx.virtualHosts.${frontendConfig.hostName}; + backendVirtualHost = config.services.nginx.virtualHosts.${backendConfig.hostName}; + redirectVirtualHost = lib.attrByPath [ + "www.rabbigerzi.com" + ] { } config.services.nginx.virtualHosts; assertions = [ { @@ -28,25 +27,23 @@ let message = "Rabbi Gerzi backend does not use the production API domain"; } { - assertion = backendConfig.corsAllowedOrigins == [ - "https://rabbigerzi.com" - "https://rabbigerzi.yisroelbaum.com" - ]; + assertion = + backendConfig.corsAllowedOrigins == [ + "https://rabbigerzi.com" + "https://rabbigerzi.yisroelbaum.com" + ]; message = "Rabbi Gerzi CORS origins do not cover production and staging"; } { - assertion = builtins.elem "rabbigerzi.yisroelbaum.com" - frontendVirtualHost.serverAliases; + assertion = builtins.elem "rabbigerzi.yisroelbaum.com" frontendVirtualHost.serverAliases; message = "Rabbi Gerzi frontend staging alias is missing"; } { - assertion = builtins.elem "rabbigerziapi.yisroelbaum.com" - backendVirtualHost.serverAliases; + assertion = builtins.elem "rabbigerziapi.yisroelbaum.com" backendVirtualHost.serverAliases; message = "Rabbi Gerzi backend staging alias is missing"; } { - assertion = redirectVirtualHost.globalRedirect or null - == "rabbigerzi.com"; + assertion = redirectVirtualHost.globalRedirect or null == "rabbigerzi.com"; message = "Rabbi Gerzi www host does not redirect to the apex"; } { @@ -63,8 +60,7 @@ let in pkgs.runCommand "rabbi-gerzi-production-domains" { - failures = lib.concatMapStringsSep "\n" - (assertion: assertion.message) failedAssertions; + failures = lib.concatMapStringsSep "\n" (assertion: assertion.message) failedAssertions; preferLocalBuild = true; } '' diff --git a/flake.nix b/flake.nix index 0506c80..fc821ec 100644 --- a/flake.nix +++ b/flake.nix @@ -59,12 +59,11 @@ } ]; }; - checks."${system}".rabbi-gerzi-domains = - import ./checks/rabbi-gerzi-domains.nix { - config = self.nixosConfigurations.nixos.config; - inherit (nixpkgs) lib; - pkgs = nixpkgs.legacyPackages.${system}; - }; + checks."${system}".rabbi-gerzi-domains = import ./checks/rabbi-gerzi-domains.nix { + config = self.nixosConfigurations.nixos.config; + inherit (nixpkgs) lib; + pkgs = nixpkgs.legacyPackages.${system}; + }; devShells."${system}".default = let pkgs = import nixpkgs { inherit system; }; From 3704a2800fc9133e8d2eeaf873c9f3b77d878c98 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 17 Aug 2026 21:19:36 +0300 Subject: [PATCH 3/5] configure production domains --- rabbi-gerzi.nix | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/rabbi-gerzi.nix b/rabbi-gerzi.nix index 8da51b0..e779de5 100644 --- a/rabbi-gerzi.nix +++ b/rabbi-gerzi.nix @@ -10,22 +10,34 @@ borgPrivateKey = config.sops.secrets."borg-private-key".path; }; frontend = { - hostName = "rabbigerzi.yisroelbaum.com"; + hostName = "rabbigerzi.com"; nginx = { forceSSL = true; enableACME = true; + serverAliases = [ "rabbigerzi.yisroelbaum.com" ]; }; }; backend = { - hostName = "rabbigerziapi.yisroelbaum.com"; + hostName = "api.rabbigerzi.com"; environmentFile = config.sops.secrets."rabbi-gerzi-env".path; + corsAllowedOrigins = [ + "https://rabbigerzi.com" + "https://rabbigerzi.yisroelbaum.com" + ]; nginx = { forceSSL = true; enableACME = true; + serverAliases = [ "rabbigerziapi.yisroelbaum.com" ]; }; }; }; + services.nginx.virtualHosts."www.rabbigerzi.com" = { + forceSSL = true; + enableACME = true; + globalRedirect = "rabbigerzi.com"; + }; + sops.secrets."rabbi-gerzi-env" = { sopsFile = ./secrets/rabbi-gerzi.env; format = "dotenv"; From a5fb2143dca298ab8afb416fdebfcbc5e663787e Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 17 Aug 2026 23:53:07 +0300 Subject: [PATCH 4/5] test redirect host configuration --- checks/rabbi-gerzi-domains.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/checks/rabbi-gerzi-domains.nix b/checks/rabbi-gerzi-domains.nix index a421860..27c9e62 100644 --- a/checks/rabbi-gerzi-domains.nix +++ b/checks/rabbi-gerzi-domains.nix @@ -22,6 +22,10 @@ let assertion = frontendConfig.apiBaseUrl == "https://api.rabbigerzi.com"; message = "Rabbi Gerzi frontend does not use the production API"; } + { + assertion = frontendConfig.redirectHostNames == [ "www.rabbigerzi.com" ]; + message = "Rabbi Gerzi frontend redirect hosts are not configured"; + } { assertion = backendConfig.hostName == "api.rabbigerzi.com"; message = "Rabbi Gerzi backend does not use the production API domain"; From cbfae24c9135d39fcafda9d44ffbf65ea3f03214 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 17 Aug 2026 23:55:01 +0300 Subject: [PATCH 5/5] use frontend redirect hosts --- rabbi-gerzi.nix | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rabbi-gerzi.nix b/rabbi-gerzi.nix index e779de5..70fd980 100644 --- a/rabbi-gerzi.nix +++ b/rabbi-gerzi.nix @@ -11,6 +11,7 @@ }; frontend = { hostName = "rabbigerzi.com"; + redirectHostNames = [ "www.rabbigerzi.com" ]; nginx = { forceSSL = true; enableACME = true; @@ -32,12 +33,6 @@ }; }; - services.nginx.virtualHosts."www.rabbigerzi.com" = { - forceSSL = true; - enableACME = true; - globalRedirect = "rabbigerzi.com"; - }; - sops.secrets."rabbi-gerzi-env" = { sopsFile = ./secrets/rabbi-gerzi.env; format = "dotenv";