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