Operations 9 min read

Implementing Jenkins as Code with Docker and Configuration‑as‑Code

This article describes how to create an immutable Jenkins instance by storing all configuration and job definitions as declarative code, building a Docker image with required plugins, using the Configuration‑as‑Code and Job‑DSL plugins, and automating setup tasks such as default user creation and wizard skipping across multiple environments.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Implementing Jenkins as Code with Docker and Configuration‑as‑Code

Since I started working with Jenkins, I have been using it for everything from supervising legacy jobs to maintaining and enhancing declarative multi‑branch pipelines, aiming to achieve continuous integration and delivery across many environments.

Achieving this level of automation requires time, team effort, and a cultural shift toward DevOps practices.

The goal is to build a Jenkins instance whose entire configuration and job definitions are stored in declarative files, making the instance immutable, version‑controlled in Git, and reproducible on any host for testing or production.

To accomplish this, I split the project into two repositories: one for instance‑level configuration (using the Configuration‑as‑Code plugin and a Dockerfile to build a base image) and another for job definitions via the Jenkins DSL plugin, storing jobs, folders, and views as Groovy code.

Building the Docker image

FROM jenkins/jenkins:lts
COPY init-scripts /usr/share/jenkins/ref/init.groovy.d
ADD plugins.txt /usr/share/jenkins/ref/
ADD jenkins.yaml /usr/share/jenkins/ref/
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
ENV CASC_JENKINS_CONFIG /usr/share/jenkins/ref/
VOLUME /var/jenkins_home

A helper shell script can build and run the image:

#!/usr/bin/env bash
docker build -t jenkins_as_code:0.1.0 .

Plugin installation

The install-plugins.sh script bundled in the Jenkins image installs plugins listed in plugins.txt , allowing version locking.

workflow-aggregator:2.6
configuration-as-code:1.30
configuration-as-code-support:1.18
credentials:2.3.0
blueocean:1.19.0
job-dsl:1.74

JCaC Jenkins plugin

This plugin lets you define global and plugin configuration via a YAML file, enabling immutable deployments and even a seed job that pulls DSL scripts from a Git repository.

jenkins:
  systemMessage: "Jenkins As Code Concept."
  views:
    - myView:
        name: "Jobs Config as Code"
  security:
    globalJobDslSecurityConfiguration:
      useScriptSecurity: false
  jobs:
    - script: >
        freeStyleJob("Jobs Generator") {
          scm {
            github('imanol-dev/jenkins_as_code_jobs', 'master')
          }
          steps {
            dsl {
              external('*.groovy')
            }
          }
        }

Changing the YAML and reloading applies all updates without recreating the Jenkins container.

Default admin user

To auto‑create a default admin, set the following environment variables in the container:

ADMIN_USERNAME=
ADMIN_PASSWORD=

Skipping the setup wizard

Disable the initial setup wizard by providing:

JAVA_OPTS="-Djenkins.install.runSetupWizard=false"

Job DSL plugin and job definitions

Jobs can be defined in a separate repository and triggered via a seed job; any changes to the DSL scripts are automatically applied, eliminating manual updates.

Conclusion

While a single Jenkins instance can serve multiple environments, sometimes isolated instances are required; using Jenkins as Code with Docker, Configuration‑as‑Code, and Job‑DSL provides a repeatable, version‑controlled way to automate repetitive and manual tasks across those instances.

dockerci/cdDevOpsJenkinsInfrastructure as CodeConfiguration as Code
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.