How to test Jenkins locally
We use Jenkins in every one of our projects. It’s a reliable tool that just works. Recently, the need to test a new change in our Jenkinsfile emerged; however, there was no way to confidently conclude this would work without testing it locally. So we needed to setup Jenkins and its pipelines locally. This is how I did it.
Let’s start with setting up Jenkins itself locally. I used Jenkins docker image and docker-compose. I believe this to be the easiest and most convenient way to run Jenkins.
This setup is only for local testing. Be aware that in this approach best practices were sacrificed for the sake of ease of use. Please do not use this solution in any environment other than local.
Create a directory like jenkins_local
and add a docker-compose.yml
file inside. The bare minimum for Jenkins inside a docker-compose.yml
should look like this:
Here we specified ajenkins
service that uses jenkins/jenkins:jdk11
image, exposes port 8080
for it, and mounts it to jenkins_home
volume.
Now run docker-compose up to spin up the container. Check the logs and look for the password Jenkins spits out for us during the initial setup. Copy it.
On your browser navigate to http://localhost:8080/. On the first run, you should be presented with the Jenkins’s Getting Started page, where you must paste the administrator password copied in the previous step.
Next, you can install suggested plugins or select your own.
Now is the time for a cup of tea while Jenkins installs all its necessary dependencies. Once that process is finished, you can fill in the form in order to create the first admin user.
On the next form, it will ask you to set Jenkins URL. We can go with the default http://localhost:8080/. Jenkins is now ready to use!
Let’s set up a pipeline now that we have Jenkins up and running locally. In the top left corner click “New Item”. Enter a pipeline name, choose Pipeline from the list below, and hit Ok.
Next you will see the pipeline configuration form. The most important setting here is where Jenkins can find the pipeline script. Choose Pipeline script from SCM for the Definition and Git for SCM.
For Repository URL, we don’t want to use a remote repository URL such as a link to a GitHub repo. The intention here is to keep it local. To do that, we want to mount our dockerized application’s project directory — which we’re testing Jenkins locally with — to our Jenkins instance. If your directory structure looks like this —
— add ../your_app:/var/jenkins_home/your_app:ro
to the local_jenkins docker-compose.yml
file. Doing this gives Jenkins access to our application files, including Jenkinsfile. “ro” is a read-only flag so Jenkins won’t be able to override any file or add something we don’t want. Also, we need to add a configuration env hudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true
to tell Jenkins that using a local file is permitted.
Going back to the Repository URL, now instead of a remote repository URL, you can use a local file path: file:////var/jenkins_home/your_app/.git
.
Then set up the branch you want Jenkins to build. Leave Script Path with default value — Jenkinsfile. Save the configuration.
If you see this error —
An internal error occurred during form field validation (HTTP 403). Please reload the page and if the problem persists, ask the administrator for help.
— just run docker-compose down
and docker-compose up
.
This should be enough for the very basic build flow. Go to Jenkins, click on your pipeline, and then select Build Now
You should see your builds now on your pipeline details page.
Keep in mind that its not enough to save changes in Jenkinsfile, you need to use git and commit them; though, actually pushing them isn’t required. Another thing to remember is to be checked out on the branch you specified during the pipeline configuration.
If you want to trigger a build using a post call to Jenkins, set up a build trigger in your pipeline configuration file. To do this, choose Trigger builds remotely (e.g., from scripts). This allows you to trigger a build by making a post request to a Jenkins pipeline you want to build (more on this later). Also, you need to set up an Authentication Token to be used when making a request. Since we’re using it solely locally, a token as simple as token
is suitable. Though for any other environment, make it as long and random as possible.
At this point, we need to add yet another configuration env to our Jenkins’s docker-compose.yml
file. Like with many other settings, CSRF protection can be skipped locally, but that’s not so in other environments.
hudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true
Now our Jenkins docker-compose.yml
file should look like this:
A user must be created first before triggering a build. In Jenkins, go to Manage Jenkins > Manage Users and click Create User. Fill in the fields — while noting the username and password — and click Create User. This newly created user needs some privileges, so go to Manage Jenkins > Configure Global Security.
Under Authorization, choose Matrix-based security, then click Add user; in the popup, enter the username of the user you just created and select Ok. Then check overall:read, job:build, job:read for this user like so —
— and save the configuration.
Make sure you have Jenkinsfile in the same directory as your_app
, go to the terminal, and run:
curl -XPOST -u user_username:user_password http://localhost:8080/job/your_pipeline_name/build?token=your_token
Your curl command should look something like this:
curl -XPOST -u jenkins:jenkins http://localhost:8080/job/test_pipeline/build?token=token
If you’re looking to trigger a build after every commit, add a post-commit file to .git/hooks
in your application directory and add a bash script there.
#!/bin/bash
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
if [[ "$BRANCH" == "jenkins_test" ]]; then
curl -XPOST -u jenkins:jenkins http://localhost:8080/job/test_pipeline/build?token=token
fi
In this example, it will only work on a specific branch — jenkins_test.
This can be any branch you want. To make sure the script is executable:
chmod +x .git/hooks/post-commit
Now the Jenkins pipeline build will trigger every time a commit is made to the jenkins_test
branch.
Thank you for reading, please follow, and feel free to add any suggestions!