1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.youtrack;
7
8 extraAttr = concatStringsSep " " (mapAttrsToList (k: v: "-D${k}=${v}") (stdParams // cfg.extraParams));
9 mergeAttrList = lib.foldl' lib.mergeAttrs {};
10
11 stdParams = mergeAttrList [
12 (optionalAttrs (cfg.baseUrl != null) {
13 "jetbrains.youtrack.baseUrl" = cfg.baseUrl;
14 })
15 {
16 "java.aws.headless" = "true";
17 "jetbrains.youtrack.disableBrowser" = "true";
18 }
19 ];
20in
21{
22 options.services.youtrack = {
23
24 enable = mkEnableOption "YouTrack service";
25
26 address = mkOption {
27 description = ''
28 The interface youtrack will listen on.
29 '';
30 default = "127.0.0.1";
31 type = types.string;
32 };
33
34 baseUrl = mkOption {
35 description = ''
36 Base URL for youtrack. Will be auto-detected and stored in database.
37 '';
38 type = types.nullOr types.string;
39 default = null;
40 };
41
42 extraParams = mkOption {
43 default = {};
44 description = ''
45 Extra parameters to pass to youtrack. See
46 https://www.jetbrains.com/help/youtrack/standalone/YouTrack-Java-Start-Parameters.html
47 for more information.
48 '';
49 example = {
50 "jetbrains.youtrack.overrideRootPassword" = "tortuga";
51 };
52 type = types.attrsOf types.string;
53 };
54
55 package = mkOption {
56 description = ''
57 Package to use.
58 '';
59 type = types.package;
60 default = pkgs.youtrack;
61 defaultText = "pkgs.youtrack";
62 };
63
64 port = mkOption {
65 description = ''
66 The port youtrack will listen on.
67 '';
68 default = 8080;
69 type = types.int;
70 };
71
72 statePath = mkOption {
73 description = ''
74 Where to keep the youtrack database.
75 '';
76 type = types.string;
77 default = "/var/lib/youtrack";
78 };
79
80 virtualHost = mkOption {
81 description = ''
82 Name of the nginx virtual host to use and setup.
83 If null, do not setup anything.
84 '';
85 default = null;
86 type = types.nullOr types.string;
87 };
88
89 jvmOpts = mkOption {
90 description = ''
91 Extra options to pass to the JVM.
92 See https://www.jetbrains.com/help/youtrack/standalone/Configure-JVM-Options.html
93 for more information.
94 '';
95 type = types.string;
96 example = "-XX:MetaspaceSize=250m";
97 default = "";
98 };
99
100 maxMemory = mkOption {
101 description = ''
102 Maximum Java heap size
103 '';
104 type = types.string;
105 default = "1g";
106 };
107
108 maxMetaspaceSize = mkOption {
109 description = ''
110 Maximum java Metaspace memory.
111 '';
112 type = types.string;
113 default = "350m";
114 };
115 };
116
117 config = mkIf cfg.enable {
118
119 systemd.services.youtrack = {
120 environment.HOME = cfg.statePath;
121 environment.YOUTRACK_JVM_OPTS = "${extraAttr}";
122 after = [ "network.target" ];
123 wantedBy = [ "multi-user.target" ];
124 serviceConfig = {
125 Type = "simple";
126 User = "youtrack";
127 Group = "youtrack";
128 ExecStart = ''${cfg.package}/bin/youtrack --J-Xmx${cfg.maxMemory} --J-XX:MaxMetaspaceSize=${cfg.maxMetaspaceSize} ${cfg.jvmOpts} ${cfg.address}:${toString cfg.port}'';
129 };
130 };
131
132 users.users.youtrack = {
133 description = "Youtrack service user";
134 isSystemUser = true;
135 home = cfg.statePath;
136 createHome = true;
137 group = "youtrack";
138 };
139
140 users.groups.youtrack = {};
141
142 services.nginx = mkIf (cfg.virtualHost != null) {
143 upstreams.youtrack.servers."${cfg.address}:${toString cfg.port}" = {};
144 virtualHosts.${cfg.virtualHost}.locations = {
145 "/" = {
146 proxyPass = "http://youtrack";
147 extraConfig = ''
148 client_max_body_size 10m;
149 proxy_http_version 1.1;
150 proxy_set_header X-Forwarded-Host $http_host;
151 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
152 proxy_set_header X-Forwarded-Proto $scheme;
153 '';
154 };
155
156 "/api/eventSourceBus" = {
157 proxyPass = "http://youtrack";
158 extraConfig = ''
159 proxy_cache off;
160 proxy_buffering off;
161 proxy_read_timeout 86400s;
162 proxy_send_timeout 86400s;
163 proxy_set_header Connection "";
164 chunked_transfer_encoding off;
165 client_max_body_size 10m;
166 proxy_http_version 1.1;
167 proxy_set_header X-Forwarded-Host $http_host;
168 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
169 proxy_set_header X-Forwarded-Proto $scheme;
170 '';
171 };
172
173 };
174 };
175
176 };
177}