Getting Jenkins Running On A Mac

I wanted to blog about how to get Jenkins running on a Mac using its installer.Jenkins is a great product, but its frenetic and crazed (but cheerful and enthusiastic) development process often shows through. Case in point: the default Mac installe…

I wanted to blog about how to get Jenkins running on a Mac using its installer.

Jenkins is a great product, but its frenetic and crazed (but cheerful and enthusiastic) development process often shows through.

Case in point: the default Mac installer, which you can download from the website, sets up Jenkins to run as a Mac LaunchDaemon running as user daemon.

Now, there's nothing inherently wrong with this–indeed, it can be quite nice.?? You'll only have one instance of Jenkins running, and no user needs to be logged on for it to do its thing, and if Jenkins ever got hacked you're running as a low-privilege user rather than as some kind of full-fledged user with the ability to ruin your day.

However, this caused some weird problems, nullifying the entire intent of a one-click installer.?? These problems manifest themselves the moment you try to run a Maven build, which suggests to me that this (simple) smoke test is simply not run before new versions of the installer are released.?? Oh well, time to roll up our sleeves and turn the one-click installation process into an exercise in Mac system administration.?? 🙂

What's wrong with daemon?

The first thing to know about user daemon is that his home directory is /var/root.?? That should start to give you a funny feeling.

The reason that should give you a funny feeling is that Maven looks for its settings.xml file in $HOME/.m2.?? Which of course does not exist in /var/root.

So when Jenkins launches, it appears to come up fine.?? But if you try to run a Maven build, you'll get a lovely stack trace about how the file /var/root/.m2 couldn't be created.

When I first encountered this error, I just wanted to get the stupid thing working, so I did:

sudo mkdir -p /var/root/.m2


sudo chmod a+rwx /var/root/.m2

So this gets Jenkins-running-as-daemon past this problem, but now it wants to create temporary files in /Users/Shared/Jenkins/Home, which it doesn't own, and can't write to.

At any rate, I now realized that I didn't want this thing running as user daemon anyway, because I didn't want him doing anything to /var/root.?? And even if I could somehow tell him to use a different user directory so that $HOME/.m2/settings.xml would be resolved somewhere else, it was clear that I was going to have to edit .plist files.?? So, so much for the installer.?? And as long as the installer wasn't going to work, I decided that I wanted to make Jenkins run as a different kind of daemon user anyway.

This turned out (for this rookie Mac system administrator) to be quite difficult.

The steps involved are:

  1. Create a daemon user (I called mine _jenkins)
  2. Create a daemon group (I called mine???surprise!???_jenkins)
  3. Put the daemon user in the newly-created daemon group
  4. Create the home directory for the new daemon user (/Users/_jenkins in my case)
  5. chown the /Users/Shared/Jenkins directory so that its hierarchy is owned by your new user.
  6. edit /Library/LaunchDaemons/org.jenkins-ci.plist so that it reflects all this information.

Creating the user is a task that should not be accomplished through the usual Mac GUI methods.?? You need to use dscl instead.?? This is because you want to create a daemon user.?? I snooped around for a bit and came up with this lovely tutorial: It walked me through steps 1-4 above.

Then I did:

sudo chown -R _jenkins:_jenkins /Users/Shared/Jenkins

Finally, my /Library/LaunchDaemons/org.jenkins-ci.plist looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
?????? <dict>
?????????????? <key>EnvironmentVariables</key>
?????????????? <dict>
?????????????????????????????? <key>JENKINS_HOME</key>
?????????????????????????????? <string>/Users/Shared/Jenkins/Home</string>
?????????????????????????????? <key>_JAVA_OPTIONS</key>
?????????????????????????????? <string>-Dfile.encoding=UTF-8</string>

?????????????? </dict>
?????????????? <key>GroupName</key>
?????????????? <string>_jenkins</string>
?????????????? <key>KeepAlive</key>
?????????????? <true/>
?????????????? <key>Label</key>
?????????????? <string>org.jenkins-ci</string>
?????????????? <key>ProgramArguments</key>
?????????????? <array>
?????????????????????????????? <string>/bin/bash</string>
?????????????????????????????? <string>/Library/Application Support/Jenkins/</string>
?????????????? </array>
?????????????? <key>RunAtLoad</key>
?????????????? <true/>
?????????????? <key>UserName</key>
?????????????? <string>_jenkins</string>
?????? </dict>

I added the _JAVA_OPTIONS environment variable to force UTF-8 encoding.?? This is because no matter what kind of encoding you might specify in your Java code, Java-on-the-Mac's character encoding for what gets put out to the terminal is MacRoman by default (?!).?? You have to get the file.encoding property passed into the JVM early enough so that it is picked up by the rest of the JVM internals, and the only way to do that is to use the special _JAVA_OPTIONS environment variable picked up by all the Java tools in $JAVA_HOME/bin.?? The only unfortunate side effect of all this is that you get a warning printed to the screen on every JVM startup that says, effectively and incomprehensibly, I am using the environment variable you told me to.

Once you've done all this, you can simply stop the launch daemon and it will automatically restart with the new values:

sudo launchctl stop org.jenkins-ci

I hope that helps other Jenkins Mac users out.

Author: Laird Nelson

Devoted husband and father; working on Helidon at the intersection of Java, Jakarta EE, architecture, Kubernetes and microservices at Oracle; open source guy; Hammond B3 player and Bainbridge Islander.

5 thoughts on “Getting Jenkins Running On A Mac”

  1. It didn’t work for me, it seems that jenkins is still running as a different user. 😦 I got an acccess denied while saving a config file on jenkins

  2. HI, many thanks for this post, unfortunately although I’ve followed the instructions as above I get hudson.util.IOException2: Failed to create a temporary file in /Users/Shared/Jenkins/Home/jobs/HelloWorldwhenever I try to create a job.My permissions for /Users/Shared/Jenkins are as follows:-drwxr-xr-x 3 _jenkins _jenkins 102 21 Oct 21:59 Jenkinsand all files under here have the same permission./Library/LaunchDaemons/org.jenkins-ci.plist looks as follows:-

     &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;;&gt;&lt;plist version=&quot;1.0&quot;&gt;&lt;dict&gt;        &lt;key&gt;EnvironmentVariables&lt;/key&gt;        &lt;dict&gt;                &lt;key&gt;JENKINS_HOME&lt;/key&gt;                &lt;string&gt;/Users/Shared/Jenkins/Home&lt;/string&gt;                &lt;key&gt;JAVA_OPTIONS&lt;/key&gt;                &lt;string&gt;-Dfile.encoding=UTF-8&lt;/string&gt;        &lt;/dict&gt;        &lt;key&gt;GroupName&lt;/key&gt;        &lt;string&gt;_jenkins&lt;/string&gt;        &lt;key&gt;KeepAlive&lt;/key&gt;        &lt;true/&gt;        &lt;key&gt;Label&lt;/key&gt;        &lt;string&gt;org.jenkins-ci&lt;/string&gt;        &lt;key&gt;ProgramArguments&lt;/key&gt;        &lt;array&gt;                &lt;string&gt;/bin/bash&lt;/string&gt;                &lt;string&gt;/Library/Application Support/Jenkins/;/string&gt;        &lt;/array&gt;        &lt;key&gt;RunAtLoad&lt;/key&gt;        &lt;true/&gt;        &lt;key&gt;UserName&lt;/key&gt;        &lt;string&gt;_jenkins&lt;/string&gt;&lt;/dict&gt;&lt;/plist&gt;

    Any help appreciated!Mandy

  3. @mandyp: From what you’ve posted, everything looks good. A stack for the IOException2 might help here.

  4. Hi, did you ever try getting UI Automation tests to run from Jenkins? I’ve been trying this but run into the issue that because I am running Jenkins as a daemon user it can’t connect to the Window Server to run the tests against the simulator. I found a workaround here: but it doesn’t seem ideal as it requires a user account to automatically login on boot. Any ideas appreciated!Thanks

Comments are closed.

%d bloggers like this: