What CI is, and where Jenkins fits
The problem continuous integration solves.
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.
$ docker run --name jenkins \-p 8080:8080 -p 50000:50000 \-v jenkins_home:/var/jenkins_home \jenkins/jenkins:lts-jdk17
Running from: /usr/share/jenkins/jenkins.war2025-06-18 09:42:14.077+0000 [id=29] INFO jenkins.InitReactorRunner$1#onAttained: Started initialization2025-06-18 09:42:16.512+0000 [id=29] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization2025-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 createdand a password generated.Please use the following password to proceed to installation:4b9c2f7e8a1d4e6b9c0f3a2d5e7b1c8aThis 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.
$ docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword4b9c2f7e8a1d4e6b9c0f3a2d5e7b1c8a
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.
pipeline {agent anystages {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.
Started by user admin[Pipeline] Start of Pipeline[Pipeline] nodeRunning on Jenkins in /var/jenkins_home/workspace/hello[Pipeline] stage[Pipeline] { (Build)[Pipeline] sh+ echo compilingcompiling+ make build[Pipeline] }[Pipeline] stage[Pipeline] { (Test)[Pipeline] sh+ make testOK: 42 passed[Pipeline] }[Pipeline] stage (Declarative: Post Actions)[Pipeline] echoGreen: the build is healthy.[Pipeline] End of PipelineFinished: 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.
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?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.