Skip to content

Commit 4f7fc6d

Browse files
nixos/glitchtip: init module (#386013)
2 parents 1eeeaa0 + dd87a30 commit 4f7fc6d

File tree

20 files changed

+3856
-16
lines changed

20 files changed

+3856
-16
lines changed

nixos/doc/manual/release-notes/rl-2505.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@
141141

142142
- [Zipline](https://zipline.diced.sh/), a ShareX/file upload server that is easy to use, packed with features, and with an easy setup. Available as [services.zipline](#opt-services.zipline.enable).
143143

144+
- [GlitchTip](https://glitchtip.com/), an open source Sentry API compatible error tracking platform. Available as [services.glitchtip](#opt-services.glitchtip.enable).
145+
144146
- [Stash](https://github.com/stashapp/stash), An organizer for your adult videos/images, written in Go. Available as [services.stash](#opt-services.stash.enable).
145147

146148
- [vsmartcard-vpcd](https://frankmorgner.github.io/vsmartcard/virtualsmartcard/README.html), a virtual smart card driver. Available as [services.vsmartcard-vpcd](#opt-services.vsmartcard-vpcd.enable).

nixos/modules/module-list.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,7 @@
15021502
./services/web-apps/gancio.nix
15031503
./services/web-apps/gerrit.nix
15041504
./services/web-apps/glance.nix
1505+
./services/web-apps/glitchtip.nix
15051506
./services/web-apps/gotify-server.nix
15061507
./services/web-apps/gotosocial.nix
15071508
./services/web-apps/grav.nix
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
{
2+
config,
3+
pkgs,
4+
lib,
5+
...
6+
}:
7+
8+
let
9+
cfg = config.services.glitchtip;
10+
pkg = cfg.package;
11+
inherit (pkg.passthru) python;
12+
13+
environment = lib.mapAttrs (
14+
_: value:
15+
if value == true then
16+
"True"
17+
else if value == false then
18+
"False"
19+
else
20+
toString value
21+
) cfg.settings;
22+
in
23+
24+
{
25+
meta.maintainers = with lib.maintainers; [
26+
defelo
27+
felbinger
28+
];
29+
30+
options = {
31+
services.glitchtip = {
32+
enable = lib.mkEnableOption "GlitchTip";
33+
34+
package = lib.mkPackageOption pkgs "glitchtip" { };
35+
36+
user = lib.mkOption {
37+
type = lib.types.str;
38+
description = "The user account under which GlitchTip runs.";
39+
default = "glitchtip";
40+
};
41+
42+
group = lib.mkOption {
43+
type = lib.types.str;
44+
description = "The group under which GlitchTip runs.";
45+
default = "glitchtip";
46+
};
47+
48+
listenAddress = lib.mkOption {
49+
type = lib.types.str;
50+
description = "The address to listen on.";
51+
default = "127.0.0.1";
52+
example = "0.0.0.0";
53+
};
54+
55+
port = lib.mkOption {
56+
type = lib.types.port;
57+
description = "The port to listen on.";
58+
default = 8000;
59+
};
60+
61+
settings = lib.mkOption {
62+
description = ''
63+
Configuration of GlitchTip. See <https://glitchtip.com/documentation/install#configuration> for more information.
64+
'';
65+
default = { };
66+
defaultText = lib.literalExpression ''
67+
{
68+
DEBUG = 0;
69+
DEBUG_TOOLBAR = 0;
70+
DATABASE_URL = lib.mkIf config.services.glitchtip.database.createLocally "postgresql://@/glitchtip";
71+
REDIS_URL = lib.mkIf config.services.glitchtip.redis.createLocally "unix://''${config.services.redis.servers.glitchtip.unixSocket}";
72+
CELERY_BROKER_URL = lib.mkIf config.services.glitchtip.redis.createLocally "redis+socket://''${config.services.redis.servers.glitchtip.unixSocket}";
73+
}
74+
'';
75+
example = {
76+
GLITCHTIP_DOMAIN = "https://glitchtip.example.com";
77+
DATABASE_URL = "postgres://postgres:postgres@postgres/postgres";
78+
};
79+
80+
type = lib.types.submodule {
81+
freeformType =
82+
with lib.types;
83+
attrsOf (oneOf [
84+
str
85+
int
86+
bool
87+
]);
88+
89+
options = {
90+
GLITCHTIP_DOMAIN = lib.mkOption {
91+
type = lib.types.str;
92+
description = "The URL under which GlitchTip is externally reachable.";
93+
example = "https://glitchtip.example.com";
94+
};
95+
96+
ENABLE_USER_REGISTRATION = lib.mkOption {
97+
type = lib.types.bool;
98+
description = ''
99+
When true, any user will be able to register. When false, user self-signup is disabled after the first user is registered. Subsequent users must be created by a superuser on the backend and organization invitations may only be sent to existing users.
100+
'';
101+
default = false;
102+
};
103+
104+
ENABLE_ORGANIZATION_CREATION = lib.mkOption {
105+
type = lib.types.bool;
106+
description = ''
107+
When false, only superusers will be able to create new organizations after the first. When true, any user can create a new organization.
108+
'';
109+
default = false;
110+
};
111+
};
112+
};
113+
};
114+
115+
environmentFiles = lib.mkOption {
116+
type = lib.types.listOf lib.types.path;
117+
default = [ ];
118+
example = [ "/run/secrets/glitchtip.env" ];
119+
description = ''
120+
Files to load environment variables from in addition to [](#opt-services.glitchtip.settings).
121+
This is useful to avoid putting secrets into the nix store.
122+
See <https://glitchtip.com/documentation/install#configuration> for more information.
123+
'';
124+
};
125+
126+
database.createLocally = lib.mkOption {
127+
type = lib.types.bool;
128+
default = true;
129+
description = ''
130+
Whether to enable and configure a local PostgreSQL database server.
131+
'';
132+
};
133+
134+
redis.createLocally = lib.mkOption {
135+
type = lib.types.bool;
136+
default = true;
137+
description = ''
138+
Whether to enable and configure a local Redis instance.
139+
'';
140+
};
141+
142+
gunicorn.extraArgs = lib.mkOption {
143+
type = lib.types.listOf lib.types.str;
144+
default = [ ];
145+
description = "Extra arguments for gunicorn.";
146+
};
147+
148+
celery.extraArgs = lib.mkOption {
149+
type = lib.types.listOf lib.types.str;
150+
default = [ ];
151+
description = "Extra arguments for celery.";
152+
};
153+
};
154+
};
155+
156+
config = lib.mkIf cfg.enable {
157+
services.glitchtip.settings = {
158+
DEBUG = lib.mkDefault 0;
159+
DEBUG_TOOLBAR = lib.mkDefault 0;
160+
PYTHONPATH = "${python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/glitchtip";
161+
DATABASE_URL = lib.mkIf cfg.database.createLocally "postgresql://@/glitchtip";
162+
REDIS_URL = lib.mkIf cfg.redis.createLocally "unix://${config.services.redis.servers.glitchtip.unixSocket}";
163+
CELERY_BROKER_URL = lib.mkIf cfg.redis.createLocally "redis+socket://${config.services.redis.servers.glitchtip.unixSocket}";
164+
GLITCHTIP_VERSION = pkg.version;
165+
};
166+
167+
systemd.services =
168+
let
169+
commonService = {
170+
wantedBy = [ "multi-user.target" ];
171+
172+
wants = [ "network-online.target" ];
173+
requires =
174+
lib.optional cfg.database.createLocally "postgresql.service"
175+
++ lib.optional cfg.redis.createLocally "redis-glitchtip.service";
176+
after =
177+
[ "network-online.target" ]
178+
++ lib.optional cfg.database.createLocally "postgresql.service"
179+
++ lib.optional cfg.redis.createLocally "redis-glitchtip.service";
180+
181+
inherit environment;
182+
};
183+
184+
commonServiceConfig = {
185+
User = cfg.user;
186+
Group = cfg.group;
187+
RuntimeDirectory = "glitchtip";
188+
StateDirectory = "glitchtip";
189+
EnvironmentFile = cfg.environmentFiles;
190+
WorkingDirectory = "${pkg}/lib/glitchtip";
191+
192+
# hardening
193+
AmbientCapabilities = "";
194+
CapabilityBoundingSet = [ "" ];
195+
DevicePolicy = "closed";
196+
LockPersonality = true;
197+
MemoryDenyWriteExecute = true;
198+
NoNewPrivileges = true;
199+
PrivateDevices = true;
200+
PrivateTmp = true;
201+
PrivateUsers = true;
202+
ProcSubset = "pid";
203+
ProtectClock = true;
204+
ProtectControlGroups = true;
205+
ProtectHome = true;
206+
ProtectHostname = true;
207+
ProtectKernelLogs = true;
208+
ProtectKernelModules = true;
209+
ProtectKernelTunables = true;
210+
ProtectProc = "invisible";
211+
ProtectSystem = "strict";
212+
RemoveIPC = true;
213+
RestrictAddressFamilies = [ "AF_INET AF_INET6 AF_UNIX" ];
214+
RestrictNamespaces = true;
215+
RestrictRealtime = true;
216+
RestrictSUIDSGID = true;
217+
SystemCallArchitectures = "native";
218+
SystemCallFilter = [
219+
"@system-service"
220+
"~@privileged"
221+
"~@resources"
222+
];
223+
UMask = "0077";
224+
};
225+
in
226+
{
227+
glitchtip = commonService // {
228+
description = "GlitchTip";
229+
230+
preStart = ''
231+
${lib.getExe pkg} migrate
232+
'';
233+
234+
serviceConfig = commonServiceConfig // {
235+
ExecStart = ''
236+
${lib.getExe python.pkgs.gunicorn} \
237+
--bind=${cfg.listenAddress}:${toString cfg.port} \
238+
${lib.concatStringsSep " " cfg.gunicorn.extraArgs} \
239+
glitchtip.wsgi
240+
'';
241+
};
242+
};
243+
244+
glitchtip-worker = commonService // {
245+
description = "GlitchTip Job Runner";
246+
247+
serviceConfig = commonServiceConfig // {
248+
ExecStart = ''
249+
${lib.getExe python.pkgs.celery} \
250+
-A glitchtip worker \
251+
-B -s /run/glitchtip/celerybeat-schedule \
252+
${lib.concatStringsSep " " cfg.celery.extraArgs}
253+
'';
254+
};
255+
};
256+
};
257+
258+
services.postgresql = lib.mkIf cfg.database.createLocally {
259+
enable = true;
260+
ensureDatabases = [ "glitchtip" ];
261+
ensureUsers = [
262+
{
263+
name = "glitchtip";
264+
ensureDBOwnership = true;
265+
}
266+
];
267+
};
268+
269+
services.redis.servers.glitchtip.enable = cfg.redis.createLocally;
270+
271+
users.users = lib.mkIf (cfg.user == "glitchtip") {
272+
glitchtip = {
273+
home = "/var/lib/glitchtip";
274+
group = cfg.group;
275+
extraGroups = lib.optionals cfg.redis.createLocally [ "redis-glitchtip" ];
276+
isSystemUser = true;
277+
};
278+
};
279+
280+
users.groups = lib.mkIf (cfg.group == "glitchtip") { glitchtip = { }; };
281+
282+
environment.systemPackages =
283+
let
284+
glitchtip-manage = pkgs.writeShellScriptBin "glitchtip-manage" ''
285+
set -o allexport
286+
${lib.toShellVars environment}
287+
${lib.concatMapStringsSep "\n" (f: "source ${f}") cfg.environmentFiles}
288+
${config.security.wrapperDir}/sudo -E -u ${cfg.user} ${lib.getExe pkg} "$@"
289+
'';
290+
in
291+
[ glitchtip-manage ];
292+
};
293+
}

nixos/tests/all-tests.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ in {
434434
gitolite-fcgiwrap = handleTest ./gitolite-fcgiwrap.nix {};
435435
glance = runTest ./glance.nix;
436436
glances = runTest ./glances.nix;
437+
glitchtip = runTest ./glitchtip.nix;
437438
glusterfs = handleTest ./glusterfs.nix {};
438439
gnome = handleTest ./gnome.nix {};
439440
gnome-extensions = handleTest ./gnome-extensions.nix {};

0 commit comments

Comments
 (0)