Note: This is part 3 of the Jenkins docker tutorial series. Click here for part 1. And here for part 2.
You want to set up a Jenkins Docker service that automatically sets up the Jenkins settings so you don't have to do it manually.
TLDR: Bitbucket code here.
There is a Jenkins plugin called Jenkins Configuration as Code (JCasC) which provides the ability to define your whole Jenkins configuration as a YAML file. In this tutorial we will extend our initial Jenkins Docker service from previous posts to utilize the JCasC plugin such that it automatically sets up the configuration for
Following plugins must be installed:
The realization as code is threefold:
We will create two global roles:
For the first point, we need to use authorizationStrategy key, where we specify roleBased before we set up the global roles.
For the latter we populate the securityRealm key, define allowsSignup: false and set the username (id) and password of the admin user.
jenkins:
systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n"
authorizationStrategy:
roleBased:
roles:
global:
- name: "admin"
description: "Jenkins administrators"
permissions:
- "Overall/Administer"
assignments:
- "admin"
- name: "readonly"
description: "Read-only users"
permissions:
- "Overall/Read"
- "Job/Read"
assignments:
- "authenticated"
securityRealm:
local:
allowsSignup: false
users:
- id: "admin"
password: "admin"
Next, we update our docker-compose.yml file.
We extend our initial compose file by adding the CASC_JENKINS_CONFIG environmental variable and bind-mounting the jenkins.yml file to that location:
version: "3.7"
services:
jenkins:
build:
context: .
args:
USER_GROUP_ID: $USER_GROUP_ID
USER_ID: $USER_ID
environment:
CASC_JENKINS_CONFIG: $REF/casc_configs/jenkins.yml
ports:
- 9080:8080
volumes:
- $HOME/data/jenkins:$JENKINS_HOME
- ./bashrc:$JENKINS_HOME/.bashrc
- ./jenkins.yml:$REF/casc_configs/jenkins.yml
Remember, that the bash variables (e.g. $REF) are exported in our helper-script docker_run.sh which now looks as following
#!/usr/bin/env bash
export USER_GROUP_ID=$(id -g)
export USER_ID=$(id -u)
export JENKINS_HOME=/var/jenkins_home
export REF=/usr/share/jenkins/ref
docker-compose "$@"
That's it.
Whenever you start the docker service now, it will parse the jenkins.yml configuration file and load the specified settings:
apoehlmann:~/workspace/blog/jenkins$ ./docker_run.sh up --build
Building jenkins
Step 1/9 : FROM jenkins/jenkins:lts
---> a3f949e5ebfd
Step 2/9 : USER root
---> Using cache
---> d6391fcb8ed0
Step 3/9 : ARG USER_GROUP_ID
---> Using cache
---> 174db0b158ea
Step 4/9 : ARG USER_ID
---> Using cache
---> 9ce5401f06e0
Step 5/9 : RUN usermod -u ${USER_ID} -g ${USER_GROUP_ID} jenkins && chown -R jenkins ${REF}
---> Running in 3bb0c3d6baf9
Removing intermediate container 3bb0c3d6baf9
---> b9385713ba6b
Step 6/9 : USER jenkins
---> Running in 02c1132e853c
Removing intermediate container 02c1132e853c
---> aa6af15a8b9e
Step 7/9 : COPY plugins.txt ${REF}/init.groovy.d/plugins.txt
---> 4567cce4e1c3
Step 8/9 : RUN install-plugins.sh < ${REF}/init.groovy.d/plugins.txt
---> Running in 880ec219900b
Creating initial locks...
Analyzing war /usr/share/jenkins/jenkins.war...
Registering preinstalled plugins...
Using version-specific update center: https://updates.jenkins.io/2.204...
Downloading plugins...
Downloading plugin: configuration-as-code from https://updates.jenkins.io/download/plugins/configuration-as-code/1.35/configuration-as-code.hpi
Downloading plugin: role-strategy from https://updates.jenkins.io/download/plugins/role-strategy/2.16/role-strategy.hpi
> role-strategy depends on configuration-as-code:1.29;resolution:=optional,matrix-auth:2.2
Skipping optional dependency configuration-as-code
Downloading plugin: matrix-auth from https://updates.jenkins.io/2.204/latest/matrix-auth.hpi
> matrix-auth depends on configuration-as-code:1.12;resolution:=optional,cloudbees-folder:6.1.0;resolution:=optional
Skipping optional dependency configuration-as-code
Skipping optional dependency cloudbees-folder
WAR bundled plugins:
Installed plugins:
configuration-as-code:1.35
matrix-auth:2.5
role-strategy:2.16
Cleaning up locks
Removing intermediate container 880ec219900b
---> e24e43fd83d2
Step 9/9 : WORKDIR $JENKINS_HOME
---> Running in 7f76199c26ab
Removing intermediate container 7f76199c26ab
---> 60ad8d96cc8f
Successfully built 60ad8d96cc8f
Successfully tagged jenkins_jenkins:latest
Creating jenkins_jenkins_1 ... done
Attaching to jenkins_jenkins_1
jenkins_1 | Running from: /usr/share/jenkins/jenkins.war
jenkins_1 | webroot: EnvVars.masterEnvVars.get("JENKINS_HOME")
...
And since the jenkins.yml file is bind-mounted into the container, changes can be applied without having to re-build the whole image. Instead you just have to edit the file and restart the service with ./docker_run.sh restart.
We can now sign in with the username and password specified in the jenkins.yml:
Since we already set up an admin user, we could now skip the default setup wizard that shows up the first time you start the Jenkins instance.
This can be done by adding the following environmental variable to the environment: block of the docker-compose.yml:
JAVA_OPTS: -Djenkins.install.runSetupWizard=false
More config examples and how the corresponding YAML blocks have to look like can be found in the demo sub-directory of the official jenkinsci Github repo.