CoursesJenkins foundations, done rightWhat CI is, and where Jenkins fits

What CI is, and where Jenkins fits

The problem continuous integration solves.

Beginner12 min · lesson 1 of 16

A five-person team. Someone edits one file, it works on their laptop, they push it. Two days later nobody else can build the app, because that developer's machine happened to have a library nobody else installed. Continuous integration (CI) exists to kill that whole category of pain. Think of it as a shared kitchen with one rule: every ingredient goes through the same inspection before it touches the meal. In software terms, every time a developer commits code (saves a snapshot into version control) and pushes it (uploads that snapshot to the shared repository), an automated system fetches the change, compiles it, runs the tests, and reports back within minutes. That compile-and-package step is a build. The test run checks the code still behaves. The ordered chain of steps that runs on every push is a pipeline.

You get back far more than you put in. Before CI, "it compiles for me" sounded like a real defence, and integration bugs showed up late, once three more changes were stacked on top and tracing the fault got expensive. With CI the pipeline becomes the one thing everybody trusts about the health of the codebase. Red or green. Same answer for everyone, on a shared server nobody can quietly fudge. Catching a broken change minutes after it lands instead of days later is the entire economic argument for CI. Continuous delivery (CD) stretches the same loop further and releases a green build automatically. This course stays on the CI foundation: build and test.

What Jenkins actually is

Jenkins is an automation server. Think of a tireless assistant who sits by the repository, notices every change, and immediately works through the checklist you wrote. It is open-source (free, source available, maintained by a community rather than a company), self-hosted (you run it on your own server or container, not a vendor's cloud), and extended through plugins, which are installable add-ons that teach Jenkins to talk to Git, Docker, Kubernetes, Slack, and over 2,000 other tools. That plugin ecosystem is the best thing about Jenkins and, as later lessons show, its largest attack surface. Jenkins itself only conducts. The plugins and your pipeline play the instruments.

The fastest way to understand Jenkins is to run one. The official container image pins a known version, keeps the install away from your host machine, and takes seconds to throw away and recreate. Read the tag lts-jdk17 in two halves. The jdk17 part means the image bundles Java 17, the runtime Jenkins needs to run at all. The lts part means Long-Term Support, the hardened release line you want in production, as opposed to the weekly bleeding-edge builds. One command gives you a real server.

terminal
$ docker run --name jenkins \
-p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts-jdk17
console (boot log)
Running from: /usr/share/jenkins/jenkins.war
2025-06-18 09:42:14.077+0000 [id=29] INFO jenkins.InitReactorRunner$1#onAttained: Started initialization
2025-06-18 09:42:16.512+0000 [id=29] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
2025-06-18 09:42:16.640+0000 [id=22] INFO hudson.WebAppMain$3#run: Jenkins is fully up and running
*************************************************************
Jenkins initial setup is required. An admin user has been created
and a password generated.
Please use the following password to proceed to installation:
4b9c2f7e8a1d4e6b9c0f3a2d5e7b1c8a
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************

That banner is your key under the doormat, except the doormat is the log file only you can read. On first boot Jenkins invents a random admin password, prints it, and refuses to open the setup wizard without it, so nobody else on the network can claim your fresh instance before you do. Copy the password and open http://localhost:8080. Port 8080 is the web interface; port 50000 is where inbound build agents dial in, which you will use in the next lesson. Paste the password into "Unlock Jenkins" and you are in. Started the container detached and scrolled past the banner? The same password sits in a file inside the container, so read it directly.

terminal
$ docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
4b9c2f7e8a1d4e6b9c0f3a2d5e7b1c8a

One detail about the plumbing will save you real grief later. Everything Jenkins knows, meaning your jobs, build history, installed plugins and stored credentials, lives in a single directory called JENKINS_HOME, which inside the container is /var/jenkins_home. It is the filing cabinet, and the container is the room around it. The -v jenkins_home:/var/jenkins_home flag moves that cabinet into a named Docker volume that outlives the container, so your setup survives a restart. Leave the flag off and every rebuild starts blank. Two snags catch most people on first boot. If docker run exits complaining the port is allocated, something else already holds 8080, so map -p 9090:8080 instead. If the password banner never shows up, the server is still starting; wait for the "Jenkins is fully up and running" line before you load the page.

Where Jenkins fits: the pipeline it runs

So what does Jenkins actually run? A pipeline, written as code in a file named Jenkinsfile that lives in your repository right next to the code it builds. It is a recipe card kept in the same box as the ingredients, so the two can never drift apart. The modern form is the declarative pipeline, a structured syntax with strong opinions about shape, and much friendlier to beginners than the older scripted style. Here is a complete, valid one.

Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo compiling && make build'
}
}
stage('Test') {
steps {
sh 'make test'
}
}
}
post {
success { echo 'Green: the build is healthy.' }
failure { echo 'Red: something broke.' }
}
}

Read it top to bottom. pipeline wraps everything. agent any tells Jenkins to run this on whichever worker machine is free. stages holds the ordered phases. Each stage has steps, and sh runs a shell command. post says what happens once the work is done, which here is a message on success or on failure. Commit that file, point a job at the repository, and every push runs exactly these steps and nothing else. Jenkins narrates the whole run in a console log, and that log is where you will live when something breaks.

console (build #7)
Started by user admin
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/hello
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] sh
+ echo compiling
compiling
+ make build
[Pipeline] }
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ make test
OK: 42 passed
[Pipeline] }
[Pipeline] stage (Declarative: Post Actions)
[Pipeline] echo
Green: the build is healthy.
[Pipeline] End of Pipeline
Finished: SUCCESS

When to pick Jenkins, and when to walk away

Here is the honest trade-off. Pick Jenkins when you have to host it yourself for compliance reasons or on an air-gapped network with no internet access, when you build in many languages, when you need a plugin no managed service offers, or when you already run Jenkins at scale and it works. Reach for a managed service like GitHub Actions or GitLab CI when your code already lives there, when nobody on the team has time to patch and back up a server, or when a small team wants working CI by this afternoon with pipelines written in YAML (a plain-text configuration format). And do not pick Jenkins if nobody will own its upkeep. The flexibility is real, so is the maintenance bill, and "set it up and forget it" is exactly how the breach stories begin.

A fresh Jenkins trusts everyone by default
Jenkins arrives like a house with every door unlocked and the lights on. Out of the box it runs builds on the controller itself, installs any plugin you click, and listens on every network interface, so the instance will answer anyone who can reach the port. The initial-password wizard guards that very first unlock and nothing after it. Almost every Jenkins security incident traces back to defaults nobody changed later: an instance left exposed with weak authentication or none at all, or a build running on the controller where it can read every stored credential. While you are setting up, never bind port 8080 to a public IP address. Unlock it over localhost or an SSH tunnel (an encrypted connection to the machine), finish setting up authentication, then treat the box as production infrastructure from the first boot instead of a toy you will harden someday.
Quick check
01Your three-person team keeps all its code on GitHub.com and has nobody to run or patch a server. Which CI choice fits best?
Incorrect — Self-host Jenkins, because it is the most powerful option misses it. The answer is B. Match the tool to whoever has to operate it. Your code already sits on GitHub and nobody is free to run a server, so a managed CI service takes away the upkeep Jenkins demands. Choose Jenkins when self-hosting, a specific plugin, or existing scale genuinely require it.
Correct — Match the tool to whoever has to operate it. Your code already sits on GitHub and nobody is free to run a server, so a managed CI service takes away the upkeep Jenkins demands. Choose Jenkins when self-hosting, a specific plugin, or existing scale genuinely require it.
Incorrect — Skip CI and run the tests manually misses it. The answer is B. Match the tool to whoever has to operate it. Your code already sits on GitHub and nobody is free to run a server, so a managed CI service takes away the upkeep Jenkins demands. Choose Jenkins when self-hosting, a specific plugin, or existing scale genuinely require it.
Incorrect — Jenkins, but turn off authentication to save setup time misses it. The answer is B. Match the tool to whoever has to operate it. Your code already sits on GitHub and nobody is free to run a server, so a managed CI service takes away the upkeep Jenkins demands. Choose Jenkins when self-hosting, a specific plugin, or existing scale genuinely require it.
02The lesson calls the Jenkins plugin ecosystem both the best thing about it and its largest attack surface. Why describe plugins that way?
Incorrect — Because the Jenkins core team maintains plugins, making them the most trusted part of the install. misses it. The answer is B. Plugins give Jenkins its reach into thousands of tools and create its biggest liability at the same time, because every plugin you install is more attackable code running on your instance.
Correct — Plugins give Jenkins its reach into thousands of tools and create its biggest liability at the same time, because every plugin you install is more attackable code running on your instance.
Incorrect — Because plugins replace build agents, so a compromised plugin can never touch a running build. misses it. The answer is B. Plugins give Jenkins its reach into thousands of tools and create its biggest liability at the same time, because every plugin you install is more attackable code running on your instance.
Incorrect — Because plugins only change how the web interface looks, so any risk is cosmetic. misses it. The answer is B. Plugins give Jenkins its reach into thousands of tools and create its biggest liability at the same time, because every plugin you install is more attackable code running on your instance.
03You start Jenkins with docker run --name jenkins -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts-jdk17 and no -v flag. It works, so you spend a week setting up jobs, plugins and credentials. Later you pull a newer image and recreate the container. What happens to all that configuration?
Incorrect — It survives, because Jenkins always mirrors JENKINS_HOME to the host automatically. misses it. The answer is D. JENKINS_HOME holds every job, plugin and secret. Without a named volume it lives only inside the container, so recreating the container wipes it.
Incorrect — It survives, because pulling a newer image carries the old container's data forward. misses it. The answer is D. JENKINS_HOME holds every job, plugin and secret. Without a named volume it lives only inside the container, so recreating the container wipes it.
Incorrect — Only the stored credentials survive; jobs and plugins get rebuilt from the image. misses it. The answer is D. JENKINS_HOME holds every job, plugin and secret. Without a named volume it lives only inside the container, so recreating the container wipes it.
Correct — JENKINS_HOME holds every job, plugin and secret. Without a named volume it lives only inside the container, so recreating the container wipes it.

Try this

Run docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword on a scratch host or disposable cluster and read the output against what this lesson described. Then change one input so it fails, and re-run: the error you get is the one you will meet in production.

Takeaway

The trap worth remembering here: a fresh Jenkins trusts everyone by default. Check that on your own systems before you need to, because it is cheaper to find on a quiet afternoon than during an incident.

Related