Getting started with Jenkins: Language Agent
Apr 24, 2021 · 5 min readThis post follows on from the Jenkins series:
This post is going to get you running a language specific Jenkins Agent. In the example we are going to follow, we will setup a Jenkins Agent running Go. This means you will be able to run Go builds within your local Jenkins instance. This method can then be extrapolated to other languages.
All of the example code used throughout this post is in a GitHub Repo.
The Dockerfile
Since we are building our own agent, we need to define a Dockerfile
that is based on a Jenkins agent. From that base, we will then install Go.
From the example repo, let’s look at the Dockerfile
:
# Source: https://github.com/benmatselby/jenkins-example/blob/main/agents/go/Dockerfile
# Base Dockerfile image: https://hub.docker.com/r/jenkins/inbound-agent/dockerfile
FROM jenkins/inbound-agent:4.7-1-jdk11
# Where we are going to install Go.
ENV GO_INSTALL_PATH /home/jenkins/go
# We need to add the GO_INSTALL_PATH to the PATH so `go` works.
ENV PATH /home/jenkins/bin:${GO_INSTALL_PATH}/bin:/usr/local/go/bin:$PATH
# The version of Go we want to install
ENV GO_VERSION 1.16
# Define the GOPATH
ENV GOPATH ${GO_INSTALL_PATH}
# CI/CD platforms normally define CI=true, so let's follow suit
ENV CI true
# Install Go
RUN curl -sL https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz > /tmp/go.tar.gz && \
tar -C /tmp -xf /tmp/go.tar.gz && \
mv /tmp/go ${GO_INSTALL_PATH} && \
rm -rf \
${GO_INSTALL_PATH}/pkg/*/cmd \
${GO_INSTALL_PATH}/pkg/bootstrap \
${GO_INSTALL_PATH}/pkg/obj \
${GO_INSTALL_PATH}/pkg/tool/*/api \
${GO_INSTALL_PATH}/pkg/tool/*/go_bootstrap \
${GO_INSTALL_PATH}/src/cmd/dist/dist \
/tmp/go.tag.gz
Although the above code is curated, let’s explain each stage.
- To save us from installing a Jenkins Agent within the container, we are going to start with a Jenkins Agent as the base Docker image.
- We then define 5 environment variables that:
- Explain where we are going to install Go.
- Puts the Go binaries in the
PATH
. - Define the version of Go we want to build.
- Arguably you could define an
ARG
here and override at build time.
- Arguably you could define an
- Define the
GOPATH
using theGO_INSTALL_PATH
environment variable. - Most CI/CD systems will define
CI=true
, so we are following suit.
- The last block of code defines the installation commands required to install Go. Extra points for trying to streamline the image we are building by removing unnecessary files.
Building the image
Now we have defined the image, we want to build it. The easiest way to build the image, is to run this command:
docker build -f agents/go/Dockerfile -t jenkins-agent:go agents/go
This command will take the Dockerfile defined by -f
, and call the image jenkins-agent:go
using the -t
argument. The last aspect of the command agents/go
explains the context that docker build
should build in (which is the folder the Dockerfile is defined in).
In the benmatselby/jenkins-example repo, I’ve created a Make target that is agnostic of the language you may be using:
# Source: https://github.com/benmatselby/jenkins-example/blob/main/Makefile
# Find all the agents, which are all folders in the `agents` folder.
AGENTS=$(shell cd ${AGENT_PATH} && find * -type d)
# We then define a build target, which depends on the make targets defined by
# the $(AGENTS) variable.
.PHONY: build $(AGENTS)
build: $(AGENTS) ## Build the Jenkins agents
# This is the Make targets for each image found
$(AGENTS): ## Build each Jenkins agent
# This is the docker command defined above, but with variables
cd ${AGENT_PATH}/${@} && docker build -t ${AGENT_NAME}:${@} .
The more Dockerfile
s we add into the repo, e.g. Node, Python, PHP, etc, the command will still work.
Running the agent
Not to cover old ground, at this point you can re-use the “Getting started with Jenkins: Agents” post to connect your agent.
Differences I would recommend:
- Name your node after the language, so instead of
smith
this would be calledgo
.
Pulling the solution together
If you have followed the previous post to setup your agent, you should now be able to define a new job with the go
label.
Let’s create a Freestyle project called go-project
. This time let’s set the Restrict where this project can be run to go
.
Leave everything else as default (for this post, but feel free to play around later), and set the shell command to go version
.
Now click Save, and you will be taken back to the Job. Click Build Now. After a few moments, you will See #1 appear in the Build History on the left hand side. Click on the blue ball. You will see the version details for Go.
Congratulations, you’ve now successfully:
- Defined a language specific agent: Go.
- This could be any language or environment you require.
- Built the docker image for the language specific agent.
- Connected the language specific agent to the Jenkins Controller.
- Run a job that has executed Go, in your agent.
What’s next
Want to go further? Then you could:
- Define more languages and play around with “tags” to make sure builds get directed to the correct agents.
- Use something like
ngrok
to expose your installation back to GitHub, to get GitHub Events.
Summary
This was a quick overview for getting a language specific Jenkins agent connected to the Jenkins controller application.
Photo by Alexander Schimmeck on Unsplash.