1 { config, lib, pkgs, ... }:
4 cfg = config.services.youtrack;
8 (lib.mkRenamedOptionModule [ "services" "youtrack" "baseUrl" ] [ "services" "youtrack" "environmentalParameters" "base-url" ])
9 (lib.mkRenamedOptionModule [ "services" "youtrack" "port" ] [ "services" "youtrack" "environmentalParameters" "listen-port" ])
10 (lib.mkRemovedOptionModule [ "services" "youtrack" "maxMemory" ] "Please instead use `services.youtrack.generalParameters`.")
11 (lib.mkRemovedOptionModule [ "services" "youtrack" "maxMetaspaceSize" ] "Please instead use `services.youtrack.generalParameters`.")
12 (lib.mkRemovedOptionModule [ "services" "youtrack" "extraParams" ] "Please migrate to `services.youtrack.generalParameters`.")
13 (lib.mkRemovedOptionModule [ "services" "youtrack" "jvmOpts" ] "Please migrate to `services.youtrack.generalParameters`.")
16 options.services.youtrack = {
17 enable = lib.mkEnableOption "YouTrack service";
19 address = lib.mkOption {
21 The interface youtrack will listen on.
23 default = "127.0.0.1";
27 package = lib.mkOption {
31 type = lib.types.package;
32 default = pkgs.youtrack;
33 defaultText = lib.literalExpression "pkgs.youtrack";
36 statePath = lib.mkOption {
38 Path were the YouTrack state is stored.
39 To this path the base version (e.g. 2023_1) of the used package will be appended.
41 type = lib.types.path;
42 default = "/var/lib/youtrack";
45 virtualHost = lib.mkOption {
47 Name of the nginx virtual host to use and setup.
48 If null, do not setup anything.
51 type = lib.types.nullOr lib.types.str;
54 autoUpgrade = lib.mkOption {
55 type = lib.types.bool;
57 description = "Whether YouTrack should auto upgrade it without showing the upgrade dialog.";
60 generalParameters = lib.mkOption {
61 type = with lib.types; listOf str;
63 General configuration parameters and other JVM options.
64 See https://www.jetbrains.com/help/youtrack/server/2023.3/youtrack-java-start-parameters.html#general-parameters
67 example = lib.literalExpression ''
69 "-Djetbrains.youtrack.admin.restore=true"
76 environmentalParameters = lib.mkOption {
77 type = lib.types.submodule {
78 freeformType = with lib.types; attrsOf (oneOf [ int str port ]);
80 listen-address = lib.mkOption {
83 description = "The interface YouTrack will listen on.";
85 listen-port = lib.mkOption {
86 type = lib.types.port;
88 description = "The port YouTrack will listen on.";
93 Environmental configuration parameters, set imperatively. The values doesn't get removed, when removed in Nix.
94 See https://www.jetbrains.com/help/youtrack/server/2023.3/youtrack-java-start-parameters.html#environmental-parameters
97 example = lib.literalExpression ''
106 config = lib.mkIf cfg.enable {
107 services.youtrack.generalParameters = [ "-Ddisable.configuration.wizard.on.upgrade=${lib.boolToString cfg.autoUpgrade}" ];
109 systemd.services.youtrack = let
110 jvmoptions = pkgs.writeTextFile {
111 name = "youtrack.jvmoptions";
112 text = (lib.concatStringsSep "\n" cfg.generalParameters);
115 package = cfg.package.override {
116 statePath = cfg.statePath;
119 after = [ "network.target" ];
120 wantedBy = [ "multi-user.target" ];
121 path = with pkgs; [ unixtools.hostname ];
123 # This detects old (i.e. <= 2022.3) installations that were not migrated yet
124 # and migrates them to the new state directory style
125 if [[ -d ${cfg.statePath}/teamsysdata ]] && [[ ! -d ${cfg.statePath}/2022_3 ]]
127 mkdir -p ${cfg.statePath}/2022_3
128 mv ${cfg.statePath}/teamsysdata ${cfg.statePath}/2022_3
129 mv ${cfg.statePath}/.youtrack ${cfg.statePath}/2022_3
131 mkdir -p ${cfg.statePath}/{backups,conf,data,logs,temp}
132 ${pkgs.coreutils}/bin/ln -fs ${jvmoptions} ${cfg.statePath}/conf/youtrack.jvmoptions
133 ${package}/bin/youtrack configure ${lib.concatStringsSep " " (lib.mapAttrsToList (name: value: "--${name}=${toString value}") cfg.environmentalParameters )}
135 serviceConfig = lib.mkMerge [
140 Restart = "on-failure";
141 ExecStart = "${package}/bin/youtrack run";
143 (lib.mkIf (cfg.statePath == "/var/lib/youtrack") {
144 StateDirectory = "youtrack";
149 users.users.youtrack = {
150 description = "Youtrack service user";
152 home = cfg.statePath;
157 users.groups.youtrack = {};
159 services.nginx = lib.mkIf (cfg.virtualHost != null) {
160 upstreams.youtrack.servers."${cfg.address}:${toString cfg.environmentalParameters.listen-port}" = {};
161 virtualHosts.${cfg.virtualHost}.locations = {
163 proxyPass = "http://youtrack";
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;
173 "/api/eventSourceBus" = {
174 proxyPass = "http://youtrack";
178 proxy_read_timeout 86400s;
179 proxy_send_timeout 86400s;
180 proxy_set_header Connection "";
181 chunked_transfer_encoding off;
182 client_max_body_size 10m;
183 proxy_http_version 1.1;
184 proxy_set_header X-Forwarded-Host $http_host;
185 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
186 proxy_set_header X-Forwarded-Proto $scheme;
193 meta.doc = ./youtrack.md;
194 meta.maintainers = [ lib.maintainers.leona ];