8 cfg = config.services.jenkins;
9 jenkinsUrl = "http://${cfg.listenAddress}:${toString cfg.port}${cfg.prefix}";
14 enable = lib.mkOption {
15 type = lib.types.bool;
18 Whether to enable the jenkins continuous integration server.
26 User the jenkins server should execute under.
30 group = lib.mkOption {
34 If the default user "jenkins" is configured then this is the primary
39 extraGroups = lib.mkOption {
40 type = lib.types.listOf lib.types.str;
47 List of extra groups that the "jenkins" user should be a part of.
52 default = "/var/lib/jenkins";
53 type = lib.types.path;
55 The path to use as JENKINS_HOME. If the default user "jenkins" is configured then
56 this is the home of the "jenkins" user.
60 listenAddress = lib.mkOption {
62 example = "localhost";
65 Specifies the bind address on which the jenkins HTTP interface listens.
66 The default is the wildcard address.
72 type = lib.types.port;
74 Specifies port number on which the jenkins HTTP interface listens.
79 prefix = lib.mkOption {
84 Specifies a urlPrefix to use with jenkins.
85 If the example /jenkins is given, the jenkins server will be
86 accessible using localhost:8080/jenkins.
90 package = lib.mkPackageOption pkgs "jenkins" { };
92 packages = lib.mkOption {
97 config.programs.ssh.package
100 defaultText = lib.literalExpression "[ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ]";
101 type = lib.types.listOf lib.types.package;
103 Packages to add to PATH for the jenkins process.
107 environment = lib.mkOption {
109 type = with lib.types; attrsOf str;
111 Additional environment variables to be passed to the jenkins process.
112 As a base environment, jenkins receives NIX_PATH from
113 {option}`environment.sessionVariables`, NIX_REMOTE is set to
114 "daemon" and JENKINS_HOME is set to the value of
115 {option}`services.jenkins.home`.
116 This option has precedence and can be used to override those
121 plugins = lib.mkOption {
123 type = lib.types.nullOr (lib.types.attrsOf lib.types.package);
125 A set of plugins to activate. Note that this will completely
126 remove and replace any previously installed plugins. If you
127 have manually-installed plugins that you want to keep while
128 using this module, set this option to
129 `null`. You can generate this set with a
130 tool such as `jenkinsPlugins2nix`.
132 example = lib.literalExpression ''
133 import path/to/jenkinsPlugins2nix-generated-plugins.nix { inherit (pkgs) fetchurl stdenv; }
137 extraOptions = lib.mkOption {
138 type = lib.types.listOf lib.types.str;
140 example = [ "--debug=9" ];
142 Additional command line arguments to pass to Jenkins.
146 extraJavaOptions = lib.mkOption {
147 type = lib.types.listOf lib.types.str;
149 example = [ "-Xmx80m" ];
151 Additional command line arguments to pass to the Java run time (as opposed to Jenkins).
155 withCLI = lib.mkOption {
156 type = lib.types.bool;
159 Whether to make the CLI available.
161 More info about the CLI available at
163 https://www.jenkins.io/doc/book/managing/cli](https://www.jenkins.io/doc/book/managing/cli) .
169 config = lib.mkIf cfg.enable {
171 # server references the dejavu fonts
174 ] ++ lib.optional cfg.withCLI cfg.package;
178 // lib.optionalAttrs cfg.withCLI {
179 # Make it more convenient to use the `jenkins-cli`.
180 JENKINS_URL = jenkinsUrl;
184 users.groups = lib.optionalAttrs (cfg.group == "jenkins") {
185 jenkins.gid = config.ids.gids.jenkins;
188 users.users = lib.optionalAttrs (cfg.user == "jenkins") {
190 description = "jenkins user";
194 extraGroups = cfg.extraGroups;
195 useDefaultShell = true;
196 uid = config.ids.uids.jenkins;
200 systemd.services.jenkins = {
201 description = "Jenkins Continuous Integration Server";
202 after = [ "network.target" ];
203 wantedBy = [ "multi-user.target" ];
207 selectedSessionVars = lib.filterAttrs (
208 n: v: builtins.elem n [ "NIX_PATH" ]
209 ) config.environment.sessionVariables;
213 JENKINS_HOME = cfg.home;
214 NIX_REMOTE = "daemon";
220 # Force .war (re)extraction, or else we might run stale Jenkins.
224 replacePlugins = lib.optionalString (cfg.plugins != null) (
226 pluginCmds = lib.mapAttrsToList (n: v: "cp ${v} ${cfg.home}/plugins/${n}.jpi") cfg.plugins;
229 rm -r ${cfg.home}/plugins || true
230 mkdir -p ${cfg.home}/plugins
231 ${lib.concatStringsSep "\n" pluginCmds}
236 rm -rf ${cfg.home}/war
240 # For reference: https://wiki.jenkins.io/display/JENKINS/JenkinsLinuxStartupScript
242 ${pkgs.jdk17}/bin/java ${lib.concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
243 --httpPort=${toString cfg.port} \
244 --prefix=${cfg.prefix} \
245 -Djava.awt.headless=true \
246 ${lib.concatStringsSep " " cfg.extraOptions}
250 until [[ $(${pkgs.curl.bin}/bin/curl -L -s --head -w '\n%{http_code}' ${jenkinsUrl} | tail -n1) =~ ^(200|403)$ ]]; do
257 StateDirectory = lib.mkIf (lib.hasPrefix "/var/lib/jenkins" cfg.home) "jenkins";
258 # For (possible) socket use
259 RuntimeDirectory = "jenkins";