diff --git a/nixos/modules/services/web-apps/glitchtip.nix b/nixos/modules/services/web-apps/glitchtip.nix index e32af666bc06..3660b83807bd 100644 --- a/nixos/modules/services/web-apps/glitchtip.nix +++ b/nixos/modules/services/web-apps/glitchtip.nix @@ -53,7 +53,7 @@ in settings = lib.mkOption { description = '' - Configuration of GlitchTip. See for more information. + Configuration of GlitchTip. See for more information and required settings. ''; default = { }; defaultText = lib.literalExpression '' @@ -61,6 +61,7 @@ in DEBUG = 0; DEBUG_TOOLBAR = 0; DATABASE_URL = lib.mkIf config.services.glitchtip.database.createLocally "postgresql://@/glitchtip"; + GLITCHTIP_DOMAIN = lib.mkIf config.services.glitchtip.nginx.createLocally "https://''${config.services.glitchtip.nginx.domain}"; GLITCHTIP_VERSION = config.services.glitchtip.package.version; GRANIAN_HOST = "127.0.0.1"; GRANIAN_PORT = 8000; @@ -71,6 +72,7 @@ in } ''; example = { + GLITCHTIP_DOMAIN = "https://glitchtip.example.com"; DATABASE_URL = "postgres://postgres:postgres@postgres/postgres"; }; @@ -84,6 +86,13 @@ in ]); options = { + GLITCHTIP_DOMAIN = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = "The URL under which GlitchTip is externally reachable."; + example = "https://glitchtip.example.com"; + default = null; + }; + GLITCHTIP_ENABLE_MCP = lib.mkOption { type = lib.types.bool; description = "Whether to enable the MCP api."; @@ -135,17 +144,31 @@ in database.createLocally = lib.mkOption { type = lib.types.bool; default = true; - description = '' - Whether to enable and configure a local PostgreSQL database server. - ''; + description = "Whether to enable and configure a local PostgreSQL database server."; + }; + + nginx = { + createLocally = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether to enable and configure a local Nginx server."; + }; + + domain = lib.mkOption { + type = lib.types.str; + example = "glitchtip.example.com"; + description = '' + Domain under which GlitchTip will be reachable. + In contrast to `settings.GLITCHTIP_DOMAIN` this option has no protocol. + It will also set `settings.GLITCHTIP_DOMAIN` with the `https://` protocol. + ''; + }; }; redis.createLocally = lib.mkOption { type = lib.types.bool; default = true; - description = '' - Whether to enable and configure a local Redis instance. - ''; + description = "Whether to enable and configure a local Redis instance."; }; }; }; @@ -180,6 +203,7 @@ in PYTHONUNBUFFERED = lib.mkDefault 1; } // lib.optionalAttrs cfg.database.createLocally { DATABASE_URL = "postgresql://@/glitchtip"; } + // lib.optionalAttrs cfg.nginx.createLocally { GLITCHTIP_DOMAIN = "https://${cfg.nginx.domain}"; } // lib.optionalAttrs cfg.redis.createLocally { REDIS_URL = "unix://${config.services.redis.servers.glitchtip.unixSocket}"; }; @@ -286,6 +310,17 @@ in }; }; + services.nginx = lib.mkIf cfg.nginx.createLocally { + enable = true; + virtualHosts.${cfg.nginx.domain} = { + forceSSL = lib.mkDefault true; + locations = { + "/".proxyPass = "http://${cfg.settings.GRANIAN_HOST}:${toString cfg.settings.GRANIAN_PORT}"; + "/static/".root = "${pkg}/lib/glitchtip"; + }; + }; + }; + services.postgresql = lib.mkIf cfg.database.createLocally { enable = true; ensureDatabases = [ "glitchtip" ]; diff --git a/nixos/tests/glitchtip.nix b/nixos/tests/glitchtip.nix index d409562c904a..149873726bef 100644 --- a/nixos/tests/glitchtip.nix +++ b/nixos/tests/glitchtip.nix @@ -1,7 +1,8 @@ { lib, ... }: let - domain = "http://glitchtip.local:8000"; + domain = "glitchtip.local"; + url = "http://${domain}"; in { @@ -16,8 +17,10 @@ in { services.glitchtip = { enable = true; - settings.GRANIAN_PORT = 8000; - settings.GLITCHTIP_DOMAIN = domain; + nginx.createLocally = true; + nginx.domain = domain; + settings.GLITCHTIP_DOMAIN = lib.mkForce url; + settings.CSRF_TRUSTED_ORIGINS = "${url},http://localhost:8000"; environmentFiles = [ (builtins.toFile "glitchtip.env" '' SECRET_KEY=8Hz7YCGzo7fiicHb8Qr22ZqwoIB7lSRx @@ -25,19 +28,23 @@ in ]; }; + services.nginx.virtualHosts.${domain}.forceSSL = false; + environment.systemPackages = [ pkgs.sentry-cli ]; - networking.hosts."127.0.0.1" = [ "glitchtip.local" ]; + networking.hosts."127.0.0.1" = [ domain ]; }; + interactive.sshBackdoor.enable = true; + interactive.defaults.virtualisation.graphics = false; + interactive.nodes.machine = { - services.glitchtip.settings.GRANIAN_HOST = "0.0.0.0"; - networking.firewall.allowedTCPPorts = [ 8000 ]; + networking.firewall.allowedTCPPorts = [ 80 ]; virtualisation.forwardPorts = [ { from = "host"; host.port = 8000; - guest.port = 8000; + guest.port = 80; } ]; }; @@ -53,7 +60,7 @@ in machine.wait_for_unit("glitchtip-worker.service") machine.wait_for_open_port(8000) - origin_url = "${domain}" + origin_url = "${url}" cookie_jar_path = "/tmp/cookies.txt" curl = f"curl -b {cookie_jar_path} -c {cookie_jar_path} -fS -H 'Origin: {origin_url}'" @@ -89,7 +96,7 @@ in # fetch dsn resp = json.loads(machine.succeed(f"{curl} {origin_url}/api/0/projects/main/test/keys/")) assert len(resp) == 1 - assert re.match(r"^http://[\da-f]+@glitchtip\.local:8000/\d+$", dsn := resp[0]["dsn"]["public"]) + assert re.match(r"^http://[\da-f]+@glitchtip\.local/\d+$", dsn := resp[0]["dsn"]["public"]) # send event machine.succeed(f"SENTRY_DSN={dsn} sentry-cli send-event -m 'hello world'") diff --git a/pkgs/by-name/gl/glitchtip/package.nix b/pkgs/by-name/gl/glitchtip/package.nix index a1e6925ef369..56ba28f73bc0 100644 --- a/pkgs/by-name/gl/glitchtip/package.nix +++ b/pkgs/by-name/gl/glitchtip/package.nix @@ -88,6 +88,14 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-cv83nqoJob8rvBOFDUIr8kVSZQesG/ml+6n7yuZqP90="; }; + postPatch = '' + echo 'import os + ALLAUTH_TRUSTED_CLIENT_IP_HEADER = os.getenv( + "ALLAUTH_TRUSTED_CLIENT_IP_HEADER", + None + )' >> glitchtip/settings.py + ''; + propagatedBuildInputs = pythonPackages; nativeBuildInputs = [