How to Install Jenkins Slave as Windows Service

If you are here through a search engine, I wrote an updated version of this article just recently.

If you are running Jenkins master on Azure, it automatically provisions Windows VM host but it’s not permanent. What if you want a permanent Windows slave? What if you want to configure a slave on an existing Windows machie? In this example, I am using my own Windows 10 desktop environment (not a good practice however) to make it a permanent Jenkins slave for this article.

I think the best way to run Jenkins slave on Windows is to install it as a Windows service. It can start automatically as Windows starts and we could programmatically check the status, start, stop and restart.

I found it quite hard to find step-by-step information on how to do it and this documentation is really old and it doesn’t work any more with much tighter security on Windows, so I’m going to summarize the right way here.

Creating a Node

  1. Logon to Jenkins with an administrative account.
  2. Go to Manage Jenkins.
  3. Click Manage Nodes.
    manage nodes
  4. Click New Node.
  5. Enter node name like “win-bld01” and click Permanent Agent and then click OK.
    enter node name
  6. Enter a path in Remote root directory of your choice and choose “Launch agent via Java Web Start” in Launch method.
    Launch agent via Java Web Start
  7. Click OK to save the setting.

Download and Configure Jenkins Slave Windows Service

  1. Download the latest Windows Service wrapper executable from http://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/
    Download the latest Windows Service wrapper executable
    I’m downloading winsw-2.2.0-net4.exe in this example.
  2. Place it to the Custom WorkDir path and rename it to jenkins-slave.exe. I am using a directory C:\Users\[My User Account]\jenkins in this example.
  3. Create jenkins-slave.xml in the same directory with the following XML. Make sure to change the values in the XML according to your environment.
<service>
  <id>JenkinsSlave</id>
  <name>Jenkins agent</name>
  <description>This service runs an agent for Jenkins automation server.</description>
  <executable>C:\Users\amaterasu48\apps\java\bin\java.exe</executable>
  <arguments>-Xrs -jar &quot;%BASE%\slave.jar&quot; -jnlpUrl https://jks.westus.cloudapp.azure.com/computer/win-bld01/slave-agent.jnlp -secret e54b3a6b958f1e400e9809808sdfs098sdf0s9bcd4938d2fca496fbbea3e889 -workDir=C:\Users\amaterasu48\jenkins</arguments>
  <logmode>rotate</logmode>
  <onfailure action="restart">
    <download from="https://jks.westus.cloudapp.azure.com/jnlpJars/slave.jar" to="%BASE%\slave.jar">
      <extensions>
        <extension classname="winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension" enabled="true" id="killOnStartup">
          <pidfile>%BASE%\jenkins_agent.pid</pidfile>
          <stoptimeout>5000</stoptimeout>
          <stopparentfirst>false</stopparentfirst>
        </extension>
      </extensions>
    </download>
  </onfailure>
</service>

For more options, please refer to the official documentation.

Also make sure to create jenkins-slave.exe.config file with the following XML cotent to prevent the executable from running on the earlier version of the .NET Framework.

<configuration>
	<startup>
		<supportedruntime version="v4.0"/>
	</startup>
</configuration>

Install Jenkins Slave

  1. Open Windows command line as Administrator.
  2. Navigate to the directory where you have jenkins-slave.exe e.g. cd C:\Users\amaterasu48\jenkins
  3. Install the service by executing the following command.
    jenkins-slave.exe install
  4. Once it’s successful, you will see a message like this.
    2019-05-22 23:17:14,486 INFO - Installing the service with id 'JenkinsSlave'
  5. Right click Windows start button and select Run. Enter services.msc to open Windows Service management console. You will see the Jenkins agent Windows service we just installed.
    Windows Service management console
  6. Right click it and Start it.

Recap

It’s not a few simple steps but as long as this can be automated, it should not be so painful. Also, if your Jenkins slave has to talk to other resources within your network, it’s wiser to run the Windows service as a domain user that has permission to other servers.

Author: admin

A software engineer in greater Seattle area

36 thoughts on “How to Install Jenkins Slave as Windows Service”

  1. The .net version thing is important. Otherwise the agent will disconnect frequently. Good work putting this together! Thank you.

  2. Works nicely. Only thing you missed is the java install. I installed AdoptOpenJDK as its open source and does not have the Oracle requires a license if used commercially

    1. Hi, Alastair.
      The service is a .NET application which does not require a JDK on the same machine. I don’t think I “missed” it. πŸ™‚

        1. I’ve been away from working on Jenkins as I’ve moved to a different company.
          That said, when I think about it carefully, yes you are right. Running a slave jar file requires JRE for sure.
          Thanks for your comment! πŸ™‚

  3. There is a typo above that causes an issue. The .conf file should be .config. The misspell of the name causes a .net < 4.0 version to be installed for the jenkins-slave.exe (original renamed to .bak), which cannot be run, and causes the error described at https://github.com/kohsuke/winsw/issues/399
    Thus make sure you name the file correct!

  4. If you are running Oracle jdk/jre on your client, and it has java web start (javaws), there is no need to setup winsw manually! Open a browser to your jenkins master on the client, go to the windows agent node on the gui. Click the Launch button and open or download the .jnlp file.Then open the file with java web start and run it. When the agent is up and running, click on File and then Install as a service. Then open services (run services.msc) and check its running.
    Note that java web start is being retired so the Jenkins devs will need to find another way to automate this.

    1. Yeah, a lot of people shy away from Oracle JDK due to its licensing term change. Plus, if you want to limit the stuff you install on your production machines, you want to as lean as possible. It’s a good practice to not to have things that your production systems don’t require. Thanks for your input though. πŸ™‚

    2. Hi, Alastair.

      Sorry that I forgot to reply to your comment. It’s been 5 months? OMG…

      I never tried to get it to work on Oracle JDK in the past, but if I remember correctly, Oracle removed Java Web Start starting from Java 11 as you mentioned. After all, I would not like to depend on Java Web Start because it is certainly a component that a server OS would not need and for a better security, we should install only the features that we need.

      Thanks for your comment, Alastair. πŸ™‚

    1. I believe bin is .NET version 2. I would go with the executable compatible with the newer version of .NET.

  5. Sorry that the configuration XML samples were totally formatted badly because an old plugin that this site was using. I removed it and reformatted them.

  6. When You have problem with this check: mixed case in className stopTimeout stopParentFirst and supportedRuntime in jenkins-slave.exe.config.

    Good luck

  7. Surprisingly, this is one of the most accessed blog post in my blog site. I wonder if there is a demand for me to come up with a PowerShell script to automate the steps.

      1. Hi, Laura.
        Yeah, it would be crazy to have to do all these steps manually on many servers. Let me find some time this week to see if I can work on it.

  8. Hi, this was really helpful to me, thank you!
    To make it work I had modified only some xml tags.
    All elements and attributes , in your example, are named in lowercase, but actually some of them should be mixed case. My final xml is like this:

    YourJenkinsSlaveServiceId
    Your Jenkins Slave Service Name
    This service runs an agent for Jenkins automation server.
    C:\Program Files\Java\JRE8\bin\java.exe
    -Xrs -jar “%BASE%\slave.jar” -jnlpUrl http://YourJenkinsServer:8080/computer/YourNodeName/slave-agent.jnlp -secret YourSecretStringConsistingOfHexadecimalCharacters -workDir=C:\YourNodeWorkDir
    rotate

    %BASE%\jenkins_agent.pid
    5000
    false

    Thank you!!

  9. Hi
    This was extremely helpful!
    I just upgraded Jenkins on my sandbox server to 2.249.3 and it broke the Windows agent. After countless searches I landed on your site and followed the instructions. I had to download the winsw-2.9.0-net461.exe since my server is Windows 2019 and it users the newer framework.
    I fixed the entry in the jankins-slave.xml to C:\Program Files\Java\jdk-1.8.0_191\bin\java.exe and started the service successfully.
    Thank you so much!

    1. Hello, Amauri. I’m happy that the article that I wrote helped you out.
      Thank you for commenting and giving me a feedback. πŸ™‚

  10. Hi I tried your steps, would you know why I’m getting this error?

    Service cannot be started. System.IO.InvalidDataException: Attribute is missing in configuration XML
    at winsw.Util.XmlHelper.SingleAttribute[TAttributeType](XmlElement node, String attributeName)
    at winsw.Extensions.WinSWExtensionDescriptor.FromXml(XmlElement node)
    at winsw.Extensions.WinSWExtensionManager.LoadExtension(String id)
    at winsw.Extensions.WinSWExtensionManager.LoadExtensions()
    at winsw.WrapperService.OnStart(String[] args)
    at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)

    1. Hello, Arturo.
      Looks like you are missing jenkins-slave.xml? Have you worked on the step #3 in the second section?

      1. This is the xml I’ve put in, can you spot any errors? Does this service have any dependencies other than .net and java?

        JenkinsSlave_W
        JenkinsSlave_W
        This service runs an agent for Jenkins automation server.
        java.exe
        -Xrs -jar “%BASE%\slave.jar” -jnlpUrl http://x.x.x.x:8080/computer/Agent_nmknte805/slave-agent.jnlp -secret xyz -workDir E:\JenkinsAgentWrapper
        rotate

        %BASE%\jenkins_agent.pid
        5000
        false

        Thanks so much for the support! πŸ™‚

        1. Fixed it… it turns out it was the names of the elements in the xml… example classname should be className…

          Thank you! πŸ™‚

  11. For me, it starts and then stops with …

    “The Jenkins agent service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.”

    My logs look like this
    2021-01-14 15:03:21,023 DEBUG – Starting WinSW in the CLI mode
    2021-01-14 15:03:21,476 INFO – Installing the service with id ‘JenkinsSlave’
    2021-01-14 15:03:21,523 DEBUG – Completed. Exit code is 0
    2021-01-14 15:04:04,746 DEBUG – Starting WinSW in the service mode
    2021-01-14 15:04:04,777 INFO – Downloading: http://#.#.#.#/jnlpJars/agent.jar to C:\mfi-jenkins\agent.jar. failOnError=False
    2021-01-14 15:04:05,418 INFO – Starting C:\Program Files\Java\jre1.8.0_271\bin\java.exe -Xrs -jar C:\mfi-jenkins\agent.jar -jnlpUrl http://#.#.#.#/computer/windows-node-1/slave-agent.jnlp -secret ***** -workDir C:\mfi-jenkins
    2021-01-14 15:04:05,434 DEBUG – Completed. Exit code is 0

  12. fixed mine. Hade to modify the xml:

    classname –> className
    stoptimeout –> stopTimeout
    stopparentfirst –> stopParentFirst

    1. Thank you for your comment Steve.
      That’s interesting because it worked for me before when I was writing this blog article. I may try it again and make modification to this article. Glad it worked for you. πŸ™‚

    2. Steve, thanks for your comment, renaming those XML element tags / attributes solved the problem with starting the service for me!

    3. Thanks to Author, this article is extremely helpful. Also, Steve, thank you! You save our time πŸ™‚

Leave a Reply

Your email address will not be published. Required fields are marked *