DEV Community

Cover image for How to Jenkins on a Local Windows Machine
Gideon
Gideon

Posted on

How to Jenkins on a Local Windows Machine

Jenkins is an open-source automation server that enables developers to build, test, and deploy their software reliably. It plays a pivotal role in the DevOps lifecycle by automating tasks, facilitating continuous integration and continuous delivery (CI/CD), and improving collaboration among development teams.

Installing Jenkins on your local Windows machine allows you to:

  • Experiment with Jenkins features without affecting a production environment.
  • Develop and test CI/CD pipelines locally.
  • Gain hands-on experience with DevOps practices.

This guide will walk you through two methods to install Jenkins on Windows:

  1. Using Docker (Recommended)
  2. Using Windows Subsystem for Linux (WSL)

We'll compare both methods and explain why using Docker is the better choice.

Method 1: Installing Jenkins Using Docker

Placeholder for Docker and Jenkins Logos

Prerequisites

  • Windows 10 or later
  • Docker Desktop installed on your machine

Steps to Install Jenkins with Docker

Step 1: Install Docker Desktop

If you haven't installed Docker Desktop:

  1. Download Docker Desktop from the official website.

Docker Desktop Download Page

  1. Check the architecture of your Windows machine (x86_64 or Arm). Here's a medium article that helps.
  2. After a successful download, run the installer and follow the on-screen instructions.
  3. After installation, launch Docker Desktop and ensure it's running.

Step 2: Pull the Jenkins Docker Image

Open Command Prompt or PowerShell and run:

docker pull jenkins/jenkins:lts
Enter fullscreen mode Exit fullscreen mode

This command downloads the latest stable (LTS) Jenkins image.

Step 3: Run Jenkins Container

docker run \
  -p 8080:8080 \
  -p 50000:50000 \
  -d \
  -v jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(which docker):/usr/bin/docker \
  jenkins/jenkins:lts
Enter fullscreen mode Exit fullscreen mode

Docker Run Command Execution


  • docker run: This is the Docker command used to create and run a new container from a specified image.

  • -p 8080:8080:

    • Purpose: Maps port 8080 of the host machine to port 8080 of the container.
    • Explanation: Jenkins uses port 8080 as its default web interface port. This mapping allows you to access the Jenkins web UI via http://localhost:8080.
  • -p 50000:50000:

    • Purpose: Maps port 50000 of the host to port 50000 of the container.
    • Explanation: Port 50000 is used by Jenkins for communication with build agents (JNLP agents). This mapping enables distributed builds and agent connections.
  • -d :

    • Purpose: Runs the container in detached mode.
    • Explanation: The container runs in the background, allowing you to continue using the terminal for other commands.
  • -v jenkins_home:/var/jenkins_home :

    • Purpose: Mounts the Docker volume jenkins_home to the container's /var/jenkins_home directory.
    • Explanation:
      • Data Persistence: Jenkins stores its configuration, plugins, and job data in /var/jenkins_home. Mounting a volume ensures that this data persists across container restarts or recreations.
      • Named Volume: Using jenkins_home as a named volume allows Docker to manage the volume, and it can be reused or backed up easily.
  • -v /var/run/docker.sock:/var/run/docker.sock :

    • Purpose: Mounts the Docker daemon socket from the host into the container.
    • Explanation:
      • Docker Control: By mounting the Docker socket, Jenkins running inside the container can communicate with the Docker daemon on the host.
      • Use Case: This is essential if you want Jenkins to build Docker images or manage Docker containers as part of your CI/CD pipelines.
  • -v $(which docker):/usr/bin/docker :

    • Purpose: Mounts the Docker executable from the host into the container at /usr/bin/docker.
    • Explanation:
      • Docker CLI Access: This makes the Docker command-line tool (docker) available inside the Jenkins container.
      • Version Consistency: Ensures that the Docker CLI inside the container matches the version installed on the host, avoiding compatibility issues.

Note: $(which docker) is a command substitution that returns the path of the Docker executable on the host system.

  • jenkins/jenkins:lts :
    • Purpose: Specifies the Docker image to use, in this case, the Jenkins Long-Term Support (LTS) version.
    • Explanation:
      • Stable Version: Using the LTS version ensures you are running a stable and well-supported release of Jenkins.
      • Image Source: The image jenkins/jenkins:lts is maintained by the Jenkins project on Docker Hub.

Summary of the Command's Purpose

This Docker command sets up a Jenkins server in a container with the capability to:

  • Persist data through the jenkins_home volume.
  • Be accessible via the web interface on localhost:8080.
  • Communicate with build agents through port 50000.
  • Interact with Docker on the host machine to build images and manage containers from within Jenkins jobs.

Why Mount Docker Socket and Executable?

By mounting both the Docker socket and executable:

  • Docker Socket (/var/run/docker.sock):

    • Grants the container access to the Docker daemon running on the host.
    • Allows Jenkins to execute Docker commands that affect the host's Docker environment.
  • Docker Executable (/usr/bin/docker):

    • Provides the docker CLI inside the container.
    • Ensures Jenkins can run Docker commands as if it were on the host.

This setup is commonly used when you need Jenkins to perform Docker-related tasks, such as:

  • Building Docker images.
  • Running Docker containers.
  • Managing Docker registries.

Security Considerations

  • Privileges: Mounting the Docker socket and executable gives the Jenkins container elevated permissions over the host's Docker daemon.
  • Risk: If the Jenkins server or any of its jobs are compromised, malicious commands could be executed on the host.
  • Mitigation:
    • Limit access to the Jenkins server.
    • Use proper authentication and authorization within Jenkins.
    • Consider using Docker-in-Docker or Docker agents with limited permissions for additional isolation.

Alternative Approaches

  • Docker-in-Docker (dind):

    • Run a separate Docker daemon inside the container.
    • Adds complexity and potential performance overhead.
    • Provides better isolation from the host's Docker daemon.
  • Docker Agents:

    • Use separate Docker containers as build agents.
    • Avoids giving the main Jenkins container direct access to the host's Docker daemon.

Example Usage in a Jenkins Pipeline

With this setup, you can create Jenkins pipelines that include steps like:

pipeline {
    agent any
    stages {
        stage('Build Docker Image') {
            steps {
                sh 'sudo docker build -t my-image .'
            }
        }
        stage('Run Docker Container') {
            steps {
                sh 'sudo docker run -d --name my-container my-image'
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This pipeline builds a Docker image and runs a container using the Docker commands available inside the Jenkins container.

Step 4: Access Jenkins Web Interface

  1. Open a web browser and navigate to http://localhost:8080.

Jenkins Unlock Screen

  1. You'll see the "Unlock Jenkins" screen. Retrieve the initial admin password by checking the Docker container logs or reading the initialAdminPassword file:
   docker exec -it <container_id> cat /var/jenkins_home/secrets/initialAdminPassword
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Command to Retrieve Password

  1. Copy the password, paste it into the web interface, and proceed with the setup.

  2. Install suggested plugins or customize as needed.

  3. Create your first admin user, and you're ready to use Jenkins!


Advantages of Using Docker

  • Portability: Docker containers can run on any machine with Docker installed.
  • Isolation: Each container is isolated, preventing conflicts with other applications.
  • Ease of Setup: Simplifies the installation process with minimal configuration.
  • Consistency: Ensures the environment is consistent across different setups.
  • Easy Cleanup: Containers can be stopped and removed without leaving residual files.

To allow the Jenkins user inside the Docker container to run Docker commands without needing to prefix them with sudo. This involves adding the Jenkins user to the Docker group inside the container.

Here's how you can do it:


Allowing Jenkins to Run Docker Commands Without sudo

By default, Docker commands require root privileges. To enable the Jenkins user inside the container to execute Docker commands without sudo, you need to add the Jenkins user to the Docker group. Here's how to do it:

Step 1: Access the Running Jenkins Container as Root

First, you'll need to access the running Jenkins container with root privileges. You can do this using the docker exec command:

docker exec -u 0 -it <container-name> bash
Enter fullscreen mode Exit fullscreen mode
  • docker exec: Runs a command in a running container.
  • -u 0: Specifies the user ID to execute the command as. 0 is the user ID for root.
  • -it: Allocates a pseudo-TTY and keeps STDIN open, allowing you to interact with the container's shell.
  • <container-name>: Replace this with the actual name or ID of your Jenkins container.
  • bash: The command to run, in this case, starting a Bash shell.

Example:

docker exec -u 0 -it jenkins-container bash
Enter fullscreen mode Exit fullscreen mode

Note: Replace jenkins-container with your container's actual name or ID.

Step 2: Add Jenkins User to the Docker Group

Once inside the container as the root user, execute the following commands:

Check if the Docker Group Exists

First, verify whether the docker group exists inside the container:

grep -i docker /etc/group
Enter fullscreen mode Exit fullscreen mode
  • If it doesn't exist, create it:
  groupadd docker
Enter fullscreen mode Exit fullscreen mode
Add Jenkins User to the Docker Group

Now, add the jenkins user to the docker group:

usermod -aG docker jenkins
Enter fullscreen mode Exit fullscreen mode
  • usermod: A command to modify a user's settings.
  • -aG docker: Appends the user to the docker group.
Verify the User's Group Membership

You can verify that the jenkins user is now part of the docker group:

groups jenkins
Enter fullscreen mode Exit fullscreen mode

You should see docker listed among the groups.

Step 3: Exit and Restart the Container

For the group membership changes to take effect, you need to restart the Jenkins container:

  1. Exit the container shell:
   exit
Enter fullscreen mode Exit fullscreen mode
  1. Restart the container:
   docker restart <container-name>
Enter fullscreen mode Exit fullscreen mode

Example:

   docker restart jenkins-container
Enter fullscreen mode Exit fullscreen mode

Step 4: Test Docker Commands in Jenkins

Now, inside your Jenkins jobs or pipelines, you should be able to run Docker commands without needing sudo.

Example Pipeline Step:

pipeline {
    agent any
    stages {
        stage('Test Docker Command') {
            steps {
                sh 'docker ps'
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This pipeline stage will list running Docker containers, and it should execute without permission errors.


Why These Steps Are Necessary

Understanding User Permissions

  • Docker Daemon Access: The Docker daemon (dockerd) listens on a Unix socket (/var/run/docker.sock) by default. Access to this socket is controlled by Unix file permissions.
  • Docker Group: Users who are members of the docker group can interact with the Docker daemon without sudo, as the socket is owned by the docker group.

Security Considerations

  • Root Privileges: Granting access to the Docker daemon is equivalent to giving root access, as Docker commands can affect the host system.
  • Caution Advised: Ensure that only trusted users and processes have this access.

Important Notes

1. Security Implications

  • Risk of Privilege Escalation: Users with access to the Docker daemon can gain root-level access to the host.
  • Best Practices:
    • Limit access to the Jenkins interface.
    • Secure your Jenkins jobs to prevent arbitrary code execution.
    • Regularly update Jenkins and its plugins to patch security vulnerabilities.

2. Alternatives to Adding Jenkins User to Docker Group

If security is a major concern, consider the following alternatives:

  • Docker-in-Docker (DinD):

    • Run a separate Docker daemon inside the Jenkins container.
    • Isolate Docker operations from the host.
    • Cons: More complex setup, potential performance overhead.
  • Use Docker Agents:

    • Instead of running Docker commands on the Jenkins master, use agents (nodes) that have Docker installed and configured.
    • Assign jobs that require Docker to these agents.
    • Pros: Better isolation, easier to manage permissions.
  • Use Pipeline Plugins:

    • Utilize plugins like the Docker Pipeline plugin, which provides DSL for building and running containers.
    • Pros: Abstracts Docker operations, can improve security.

3. Ensure Consistent Docker Versions

  • Since you're mounting the Docker executable and socket from the host, make sure that the versions are compatible with the Jenkins environment inside the container.
  • Incompatibilities can lead to unexpected behavior or errors.

Method 2: Installing Jenkins on Windows Subsystem for Linux (WSL)

Placeholder for WSL and Jenkins Logos

Prerequisites

  • Windows 10 Version 2004 or higher
  • Windows Subsystem for Linux (WSL) enabled
  • A Linux distribution installed (e.g., Ubuntu from Microsoft Store)

Steps to Install Jenkins on WSL

Step 1: Enable WSL

  1. Open PowerShell as Administrator.
  2. Run:
   wsl --install
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of WSL Installation Command

  1. Restart your computer if prompted.

Step 2: Install a Linux Distribution

  1. Open the Microsoft Store.
  2. Search for Ubuntu and install it.

Placeholder for Screenshot of Ubuntu in Microsoft Store

  1. Launch Ubuntu from the Start menu.

Step 3: Update Linux Packages

In the Ubuntu terminal, run:

sudo apt update
sudo apt upgrade -y
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Package Update Commands

Step 4: Install Java

Jenkins requires Java. Install it using:

sudo apt install openjdk-21-jre -y
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Java Installation Command

Step 5: Add Jenkins Repository and Key

  1. Add the Jenkins Debian repository key:
   wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
Enter fullscreen mode Exit fullscreen mode
  1. Add the repository to the sources list:
   sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Adding Jenkins Repository

Step 6: Install Jenkins

Update packages and install Jenkins:

sudo apt update
sudo apt install jenkins -y
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Jenkins Installation Command

Step 7: Start Jenkins Service

sudo service jenkins start
Enter fullscreen mode Exit fullscreen mode

Verify Jenkins is running:

sudo service jenkins status
Enter fullscreen mode Exit fullscreen mode

Placeholder for Screenshot of Jenkins Service Status

Step 8: Access Jenkins Web Interface

  • Open a web browser and navigate to http://localhost:8080.

Placeholder for Screenshot of Jenkins Unlock Screen via WSL

  • Retrieve the initial admin password:
cat /var/lib/jenkins/secrets/initialAdminPassword
Enter fullscreen mode Exit fullscreen mode
  • Continue with the setup as described in the Docker method.

Advantages of Using WSL

  • Linux Environment: Provides a genuine Linux environment on Windows.
  • Direct Access: Ability to use Linux commands and tools directly.
  • Integration: Seamless integration between Windows and Linux file systems.

Why Docker is the Better Method

While both methods allow you to run Jenkins locally, using Docker has several advantages over WSL:

  1. Simplified Setup: Docker requires fewer steps and configurations.
  2. Resource Efficiency: Docker containers are lightweight compared to running a full Linux distribution in WSL.
  3. Isolation: Docker provides better isolation, reducing potential conflicts.
  4. Consistency Across Environments: Docker ensures that the Jenkins instance behaves the same across different systems.
  5. Easier Maintenance: Updating or removing Jenkins is straightforward with Docker commands.
  6. Portability: Docker images can be easily shared and deployed on other machines or servers.

In contrast, WSL may present challenges such as networking configurations, potential performance overhead, and a more complex setup process.


Conclusion

Installing Jenkins locally on your Windows machine empowers you to develop and test CI/CD pipelines in a controlled environment. While both Docker and WSL methods are viable, Docker offers a more streamlined, efficient, and beginner-friendly approach.

By leveraging Jenkins in your DevOps cycle, you can:

  • Automate repetitive tasks.
  • Enhance collaboration between development and operations teams.
  • Accelerate software delivery.
  • Improve code quality through continuous integration and testing.

Jenkins Dashboard Screenshot


Happy Building with Jenkins!

Top comments (0)