From b28a56e55f771006c00879d0224ef3454cbe3b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Fri, 6 Mar 2026 00:50:57 +0100 Subject: [PATCH] glitchtip: 5.2.1 -> 6.0.9 Diff: https://gitlab.com/glitchtip/glitchtip-backend/-/compare/v5.2.1...v6.0.9 Changelog: https://gitlab.com/glitchtip/glitchtip-backend/-/blob/v6.0.9/CHANGELOG --- nixos/modules/services/web-apps/glitchtip.nix | 134 ++++++++++-------- nixos/tests/glitchtip.nix | 4 +- pkgs/by-name/gl/glitchtip/frontend.nix | 11 +- pkgs/by-name/gl/glitchtip/package.nix | 35 ++--- 4 files changed, 99 insertions(+), 85 deletions(-) diff --git a/nixos/modules/services/web-apps/glitchtip.nix b/nixos/modules/services/web-apps/glitchtip.nix index 6a74cda886a1..e32af666bc06 100644 --- a/nixos/modules/services/web-apps/glitchtip.nix +++ b/nixos/modules/services/web-apps/glitchtip.nix @@ -45,19 +45,6 @@ in default = "glitchtip"; }; - listenAddress = lib.mkOption { - type = lib.types.str; - description = "The address to listen on."; - default = "127.0.0.1"; - example = "0.0.0.0"; - }; - - port = lib.mkOption { - type = lib.types.port; - description = "The port to listen on."; - default = 8000; - }; - stateDir = lib.mkOption { type = lib.types.path; description = "State directory of glitchtip."; @@ -74,12 +61,16 @@ in DEBUG = 0; DEBUG_TOOLBAR = 0; DATABASE_URL = lib.mkIf config.services.glitchtip.database.createLocally "postgresql://@/glitchtip"; + GLITCHTIP_VERSION = config.services.glitchtip.package.version; + GRANIAN_HOST = "127.0.0.1"; + GRANIAN_PORT = 8000; + GRANIAN_STATIC_PATH_MOUNT = "''${config.services.glitchtip.package}/lib/glitchtip/static"; + GRANIAN_WORKERS = 1; + PYTHONUNBUFFERED = 1; REDIS_URL = lib.mkIf config.services.glitchtip.redis.createLocally "unix://''${config.services.redis.servers.glitchtip.unixSocket}"; - CELERY_BROKER_URL = lib.mkIf config.services.glitchtip.redis.createLocally "redis+socket://''${config.services.redis.servers.glitchtip.unixSocket}"; } ''; example = { - GLITCHTIP_DOMAIN = "https://glitchtip.example.com"; DATABASE_URL = "postgres://postgres:postgres@postgres/postgres"; }; @@ -93,10 +84,22 @@ in ]); options = { - GLITCHTIP_DOMAIN = lib.mkOption { - type = lib.types.str; - description = "The URL under which GlitchTip is externally reachable."; - example = "https://glitchtip.example.com"; + GLITCHTIP_ENABLE_MCP = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable the MCP api."; + default = false; + }; + + GRANIAN_WORKERS = lib.mkOption { + type = lib.types.ints.positive; + description = "Number of granian workers to start"; + default = 1; + }; + + ENABLE_OBSERVABILITY_API = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable the Prometheus metrics endpoint."; + default = false; }; ENABLE_USER_REGISTRATION = lib.mkOption { @@ -144,37 +147,47 @@ in Whether to enable and configure a local Redis instance. ''; }; - - gunicorn.extraArgs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Extra arguments for gunicorn."; - }; - - celery.extraArgs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = "Extra arguments for celery."; - }; }; }; + imports = [ + (lib.mkRenamedOptionModule + [ "services" "glitchtip" "listenAddress" ] + [ "services" "glitchtip" "settings" "GRANIAN_HOST" ] + ) + (lib.mkRenamedOptionModule + [ "services" "glitchtip" "port" ] + [ "services" "glitchtip" "settings" "GRANIAN_PORT" ] + ) + (lib.mkRemovedOptionModule [ "services" "glitchtip" "celery" "extraArgs" ] + "GlitchTip 6 migrated away from celery. Please check the upstream docs how to handle your usecase now." + ) + (lib.mkRemovedOptionModule [ "services" "glitchtip" "gunicorn" "extraArgs" ] + "GlitchTip 6 migrated away from gunicorn. Please check the upstream docs how to handle your usecase now." + ) + ]; + config = lib.mkIf cfg.enable { services.glitchtip.settings = { DEBUG = lib.mkDefault 0; DEBUG_TOOLBAR = lib.mkDefault 0; - PYTHONPATH = "${python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/glitchtip"; - DATABASE_URL = lib.mkIf cfg.database.createLocally "postgresql://@/glitchtip"; - REDIS_URL = lib.mkIf cfg.redis.createLocally "unix://${config.services.redis.servers.glitchtip.unixSocket}"; - CELERY_BROKER_URL = lib.mkIf cfg.redis.createLocally "redis+socket://${config.services.redis.servers.glitchtip.unixSocket}"; GLITCHTIP_VERSION = pkg.version; + GRANIAN_HOST = lib.mkDefault "127.0.0.1"; + GRANIAN_PORT = lib.mkDefault 8000; + GRANIAN_STATIC_PATH_MOUNT = "${pkg}/lib/glitchtip/static"; + GRANIAN_WORKERS = lib.mkDefault 1; + PYTHONPATH = "${python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/glitchtip"; + PYTHONUNBUFFERED = lib.mkDefault 1; + } + // lib.optionalAttrs cfg.database.createLocally { DATABASE_URL = "postgresql://@/glitchtip"; } + // lib.optionalAttrs cfg.redis.createLocally { + REDIS_URL = "unix://${config.services.redis.servers.glitchtip.unixSocket}"; }; systemd.services = let commonService = { wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; requires = lib.optional cfg.database.createLocally "postgresql.target" @@ -235,31 +248,40 @@ in { glitchtip = commonService // { description = "GlitchTip"; + environment = + environment + // lib.optionalAttrs (cfg.settings.ENABLE_OBSERVABILITY_API && cfg.settings.WORKERS > 1) { + PROMETHEUS_MULTIPROC_DIR = "/tmp/prometheus_multiproc"; + }; + bindsTo = [ "glitchtip-worker.service" ]; + before = [ "glitchtip-worker.service" ]; preStart = '' ${lib.getExe pkg} migrate + ${lib.getExe pkg} createcachetable + ${lib.getExe pkg} maintain_partitions ''; serviceConfig = commonServiceConfig // { ExecStart = '' - ${lib.getExe python.pkgs.gunicorn} \ - --bind=${cfg.listenAddress}:${toString cfg.port} \ - ${lib.concatStringsSep " " cfg.gunicorn.extraArgs} \ - glitchtip.wsgi + ${lib.getExe python.pkgs.granian} \ + --interface ${if cfg.settings.GLITCHTIP_ENABLE_MCP then "asgi" else "asginl"} \ + glitchtip.asgi:application \ + --host ${cfg.settings.GRANIAN_HOST} \ + --port ${toString cfg.settings.GRANIAN_PORT} \ + --workers ${toString cfg.settings.GRANIAN_WORKERS} \ + --no-ws ''; }; }; glitchtip-worker = commonService // { description = "GlitchTip Job Runner"; - + environment = environment // { + IS_WORKER = "1"; + }; serviceConfig = commonServiceConfig // { - ExecStart = '' - ${lib.getExe python.pkgs.celery} \ - -A glitchtip worker \ - -B -s /run/glitchtip/celerybeat-schedule \ - ${lib.concatStringsSep " " cfg.celery.extraArgs} - ''; + ExecStart = "${lib.getExe pkg} runworker --scheduler"; }; }; }; @@ -289,15 +311,13 @@ in systemd.tmpfiles.settings.glitchtip."${cfg.stateDir}/uploads".d = { inherit (cfg) user group; }; - environment.systemPackages = - let - glitchtip-manage = pkgs.writeShellScriptBin "glitchtip-manage" '' - set -o allexport - ${lib.toShellVars environment} - ${lib.concatMapStringsSep "\n" (f: "source ${f}") cfg.environmentFiles} - ${config.security.wrapperDir}/sudo -E -u ${cfg.user} ${lib.getExe pkg} "$@" - ''; - in - [ glitchtip-manage ]; + environment.systemPackages = [ + (pkgs.writeShellScriptBin "glitchtip-manage" '' + set -o allexport + ${lib.toShellVars environment} + ${lib.concatMapStringsSep "\n" (f: "source ${f}") cfg.environmentFiles} + ${config.security.wrapperDir}/sudo -E -u ${cfg.user} ${lib.getExe pkg} "$@" + '') + ]; }; } diff --git a/nixos/tests/glitchtip.nix b/nixos/tests/glitchtip.nix index 21b3a0197c48..d409562c904a 100644 --- a/nixos/tests/glitchtip.nix +++ b/nixos/tests/glitchtip.nix @@ -16,7 +16,7 @@ in { services.glitchtip = { enable = true; - port = 8000; + settings.GRANIAN_PORT = 8000; settings.GLITCHTIP_DOMAIN = domain; environmentFiles = [ (builtins.toFile "glitchtip.env" '' @@ -31,7 +31,7 @@ in }; interactive.nodes.machine = { - services.glitchtip.listenAddress = "0.0.0.0"; + services.glitchtip.settings.GRANIAN_HOST = "0.0.0.0"; networking.firewall.allowedTCPPorts = [ 8000 ]; virtualisation.forwardPorts = [ { diff --git a/pkgs/by-name/gl/glitchtip/frontend.nix b/pkgs/by-name/gl/glitchtip/frontend.nix index 07f14a72c636..2642e460075c 100644 --- a/pkgs/by-name/gl/glitchtip/frontend.nix +++ b/pkgs/by-name/gl/glitchtip/frontend.nix @@ -5,22 +5,27 @@ fetchNpmDeps, jq, moreutils, + nodejs_22, }: buildNpmPackage (finalAttrs: { pname = "glitchtip-frontend"; - version = "5.2.1"; + version = "6.0.9"; src = fetchFromGitLab { owner = "glitchtip"; repo = "glitchtip-frontend"; tag = "v${finalAttrs.version}"; - hash = "sha256-aqGgaVjJogG3mDooQVpR59SR0HDuMPfKuB1i0Z/AMs8="; + hash = "sha256-NbAsiyX1nJLqhqEmkSHc2IlVdgKDqximhAQSJPEM2QM="; }; + nodejs = nodejs_22; + npmDeps = fetchNpmDeps { + name = "${finalAttrs.pname}-${finalAttrs.version}-npm-deps"; inherit (finalAttrs) src; - hash = "sha256-urho5XwUJL7m8/xxv9EvH0MxQIW5TG7nOBSIa77RhJc="; + npmDepsFetcherVersion = 3; + hash = "sha256-CH8fGLppFp+uivhx3gpo8vNAYHtCv0EBTLKGUAhrvSw="; }; postPatch = '' diff --git a/pkgs/by-name/gl/glitchtip/package.nix b/pkgs/by-name/gl/glitchtip/package.nix index 1c420539e06b..a1e6925ef369 100644 --- a/pkgs/by-name/gl/glitchtip/package.nix +++ b/pkgs/by-name/gl/glitchtip/package.nix @@ -2,7 +2,6 @@ lib, python313, fetchFromGitLab, - fetchPypi, callPackage, stdenv, makeWrapper, @@ -13,19 +12,7 @@ let python = python313.override { self = python; packageOverrides = final: prev: { - django = final.django_5; - django-csp = prev.django-csp.overridePythonAttrs rec { - version = "4.0"; - src = fetchPypi { - inherit version; - pname = "django_csp"; - hash = "sha256-snAQu3Ausgo9rTKReN8rYaK4LTOLcPvcE8OjvShxKDM="; - }; - }; - django-ninja-cursor-pagination = prev.django-ninja-cursor-pagination.overridePythonAttrs { - # checks are failing with django 5 - doCheck = false; - }; + django = final.django_6; }; }; @@ -36,14 +23,11 @@ let anonymizeip boto3 brotli - celery - celery-batches cxxfilt django django-allauth django-anymail django-cors-headers - django-csp django-environ django-extensions django-import-export @@ -55,21 +39,24 @@ let django-prometheus django-storages django-valkey + django-vcache + django-vtasks + duckdb google-cloud-logging granian - gunicorn + mcp + minidump orjson psycopg pydantic sentry-sdk symbolic user-agents - uvicorn + uuid6 uwsgi-chunked whitenoise ] - ++ celery.optional-dependencies.redis - ++ celery.optional-dependencies.sqlalchemy + ++ lib.optional (pythonOlder "3.14") zstandard ++ django-allauth.optional-dependencies.headless-spec ++ django-allauth.optional-dependencies.mfa ++ django-allauth.optional-dependencies.socialaccount @@ -78,8 +65,10 @@ let ++ django-storages.optional-dependencies.google ++ django-valkey.optional-dependencies.libvalkey ++ django-valkey.optional-dependencies.lz4 + ++ django-vtasks.optional-dependencies.valkey ++ granian.optional-dependencies.reload ++ granian.optional-dependencies.uvloop + ++ mcp.optional-dependencies.cli ++ psycopg.optional-dependencies.c ++ psycopg.optional-dependencies.pool ++ pydantic.optional-dependencies.email; @@ -89,14 +78,14 @@ in stdenv.mkDerivation (finalAttrs: { pname = "glitchtip"; - version = "5.2.1"; + version = "6.0.9"; pyproject = true; src = fetchFromGitLab { owner = "glitchtip"; repo = "glitchtip-backend"; tag = "v${finalAttrs.version}"; - hash = "sha256-FxkIbSrIyvLnD9n/Cb2udOhsnoC/bwGAfCRB1L/fhwo="; + hash = "sha256-cv83nqoJob8rvBOFDUIr8kVSZQesG/ml+6n7yuZqP90="; }; propagatedBuildInputs = pythonPackages;