Chapter 20: Jenkins Manual Jobs — Install, Configure and Freestyle
20.2 Install Jenkins LTS on Linux (honest flow)
In short: Jenkins is a Java program, and the way you install it decides how easy your life is for the next three years.
Why: the problem
Jenkins is a Java program, and the way you install it decides how easy your life is for the next three years. Many freshers copy an old blog post, add a package URL that no longer exists, or install a random Java version, and then spend a day fighting errors like NO_PUBKEY or "Running with Java 11 which is older than the minimum required version". At a Pune fintech, a team installed Jenkins from a stale guide; the signing key had expired, apt refused all updates, and they sat on an old Jenkins with known security bugs for months. The honest way is simple: use the official LTS repository from pkg.jenkins.io with its current key, a supported Java (17 or 21), systemd to run it, and a firewall rule for port 8080. On a laptop, the official Docker image does all of this for you. In this lesson you will install Jenkins both ways, on an Ubuntu 22.04 VM or EC2 and in Docker, check the service, and build a small custom image that already has Node.js, which this chapter needs for the badge project.
What we will build
You will install Jenkins LTS on Ubuntu with apt from the official stable repository, using Java 17. You will check the service with systemctl and journalctl, open port 8080, and read the first password. Then you will build a custom Docker image, ravi/jenkins-node, from jenkins/jenkins:lts-jdk17 with Node.js 20 added, and run it on the ci network. All later lessons in this chapter use that container.
What: every term in plain English
- pkg.jenkins.io — The official Jenkins package site. debian-stable is the LTS line for Ubuntu and Debian.
- Signing key — A public key apt uses to check that packages really come from Jenkins.
- OpenJDK 17 / 21 — Java versions supported by current Jenkins LTS. Older Java will not start it.
- systemd — The Linux service manager. systemctl starts, stops and checks Jenkins.
- journalctl — Reads service logs, for example journalctl -u jenkins.
- /var/lib/jenkins — JENKINS_HOME for a package install. In Docker it is /var/jenkins_home.
- Custom image — Your own Docker image built FROM the official one, with extra tools added.
- ufw — Ubuntu's simple firewall tool.
How: step by step
-
Install Java 17
sudo apt-get update sudo apt-get install -y fontconfig openjdk-17-jre java -versionWhat it does: Jenkins needs a supported Java first.
Output
openjdk version "17.0.12" 2024-07-16 -
Add the Jenkins key
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.keyWhat it does: Downloads the current signing key from the official site.
Output
saved [3175/3175] -
Add the LTS repository
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.listWhat it does: Tells apt where Jenkins LTS packages live, signed by that key.
Output
deb [signed-by=...] https://pkg.jenkins.io/debian-stable binary/ -
Install Jenkins
sudo apt-get update sudo apt-get install -y jenkinsWhat it does: Installs the package and a systemd service.
Output
Setting up jenkins (2.479.3) ... -
Check the service
sudo systemctl status jenkins --no-pager | head -5What it does: Shows if Jenkins is running.
Output
Active: active (running) since Sun 2026-10-25 10:20:11 IST -
Open the port
sudo ufw allow 8080/tcp sudo ufw status | grep 8080What it does: Lets your browser reach Jenkins. On EC2, also allow 8080 from your IP in the security group.
Output
8080/tcp ALLOW Anywhere -
Read the first password
sudo cat /var/lib/jenkins/secrets/initialAdminPasswordWhat it does: Used once in the setup wizard.
Output
a1b2c3d4e5f60718293a4b5c6d7e8f90
Example 1: One script that installs Jenkins LTS on a fresh Ubuntu 22
Stack. Ubuntu 22.04, OpenJDK 17, apt, systemd
Goal. One script that installs Jenkins LTS on a fresh Ubuntu 22.04 VM and checks it.
install-jenkins.sh
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update -y
sudo apt-get install -y fontconfig openjdk-17-jre curl wget
sudo wget -q -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" \
| sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update -y
sudo apt-get install -y jenkins
sudo systemctl enable --now jenkins
for i in $(seq 1 30); do
code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/login || true)
[ "$code" = "200" ] && break
sleep 2
done
echo "HTTP $code"
jenkins --version
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
What each line does
openjdk-17-jre— A supported Java runtime. fontconfig avoids font errors in charts.signed-by=...— apt trusts only this key for this repository.debian-stable— The LTS line. debian (without -stable) is the weekly line; do not use it on servers.systemctl enable --now— Starts Jenkins now and on every boot.for i in $(seq 1 30)— Waits up to a minute for Jenkins to answer, instead of a blind sleep.jenkins --version— Prints the installed version for your notes.
Green output
Setting up jenkins (2.479.3) ...
Created symlink /etc/systemd/system/multi-user.target.wants/jenkins.service
HTTP 200
2.479.3
a1b2c3d4e5f60718293a4b5c6d7e8f90
Expected result. Jenkins answers on port 8080 and starts again after a reboot.
Example 2: A custom Jenkins image with Node
Stack. Docker, Jenkins LTS, Node.js 20
Goal. A custom Jenkins image with Node.js 20, for the badge project.
Dockerfile
FROM jenkins/jenkins:lts-jdk17
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates gnupg \
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
USER jenkins
ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=true"
build-and-run.sh
docker build -t ravi/jenkins-node:lts .
docker rm -f jenkins 2>/dev/null || true
docker run -d --name jenkins --network ci -p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home ravi/jenkins-node:lts
docker exec jenkins node --version
docker exec jenkins npm --version
What each line does
FROM jenkins/jenkins:lts-jdk17— Start from the official LTS image so updates stay simple.USER root ... USER jenkins— Install as root, then go back to the jenkins user. Never run Jenkins itself as root.deb.nodesource.com/setup_20.x— The NodeSource script that adds the Node.js 20 apt repository.rm -rf /var/lib/apt/lists/*— Removes the apt cache to keep the image small.-v jenkins_home:...— Reuses the same volume, so jobs from lesson 20.1 are still there.
Green output
Successfully tagged ravi/jenkins-node:lts
jenkins
v20.18.0
10.8.2
Expected result. Jenkins is back with your old jobs, and every build can now run node and npm.
Example 3: Read the service logs when Jenkins does not start
Stack. systemd, journalctl
Goal. Read the service logs when Jenkins does not start.
debug-start.sh
sudo systemctl status jenkins --no-pager | sed -n 1,6p
sudo journalctl -u jenkins --since "10 min ago" --no-pager | tail -15
sudo ss -ltnp | grep 8080 || echo "nothing on 8080"
df -h /var/lib/jenkins | tail -1
java -version 2>&1 | head -1
What each line does
systemctl status— Shows active, failed or activating, plus the last log lines.journalctl -u jenkins— Full service log. Java errors appear here.ss -ltnp— Shows which program listens on port 8080.df -h— A full disk stops Jenkins from writing and starting.java -version— A wrong Java is the most common install error.
Green output
x jenkins.service - Jenkins Continuous Integration Server
Active: failed (Result: exit-code) since Sun 2026-10-25 10:31:02 IST
Oct 25 10:31:01 lab jenkins[4120]: Running with Java 11 from /usr/lib/jvm/java-11-openjdk-amd64,
which is older than the minimum required version (Java 17).
Oct 25 10:31:01 lab jenkins[4120]: Supported Java versions are: [17, 21]
nothing on 8080
/dev/xvda1 20G 6.1G 14G 31% /
openjdk version "11.0.24" 2024-07-16
Expected result. The log names the problem: Java 11. Install openjdk-17-jre, run sudo update-alternatives --config java, choose 17, and restart.
Verify: did it work?
-
Package version
apt-cache policy jenkins | head -3What it does: Shows installed and available LTS versions.
Output
jenkins: Installed: 2.479.3 Candidate: 2.479.3 -
Service enabled at boot
systemctl is-enabled jenkinsWhat it does: enabled means it starts after reboot.
Output
enabled -
Container has Node
docker exec jenkins node --versionWhat it does: Node is inside the Jenkins container.
Output
v20.18.0
When it is red 1
NO_PUBKEY 5BA31D57EF5975CA
Cause. The key file is old or missing, so apt cannot check the repository.
Fix, step by step
- Download the key again from pkg.jenkins.io/debian-stable/jenkins.io-2023.key.
- Check the signed-by path matches the file.
- Run sudo apt-get update again.
When it is red 2
Running with Java 11 ... older than the minimum required version
Cause. The default Java is too old.
Fix, step by step
- Install openjdk-17-jre.
- sudo update-alternatives --config java and pick 17.
- sudo systemctl restart jenkins.
When it is red 3
Site cannot be reached on EC2 public IP:8080
Cause. The security group or ufw blocks 8080.
Fix, step by step
- Add an inbound rule for TCP 8080 from your IP only.
- sudo ufw allow 8080/tcp.
- Test from the VM: curl -I localhost:8080/login.
When it is red 4
docker: permission denied while trying to connect to the Docker daemon socket
Cause. Your user is not in the docker group.
Fix, step by step
- sudo usermod -aG docker $USER.
- Log out and in again.
Cleanup
-
Stop the VM Jenkins if you used Docker instead
sudo systemctl disable --now jenkinsWhat it does: Frees port 8080 on the VM.
Output
Removed /etc/systemd/system/multi-user.target.wants/jenkins.service. -
Remove old images
docker image prune -fWhat it does: Deletes dangling image layers from the build.
Output
Total reclaimed space: 412MB
Ravindra Bagale's Tip
Junya blog madhla URL copy karu naka. Official pkg.jenkins.io aani Java 17 vapra. Lakshat theva!
Practice tasks
Easy Note your versions
Why: Bug reports need versions.
What to do: Record Jenkins, Java and OS versions.
- jenkins --version
- java -version
- lsb_release -a
Check: Three versions written in your notes.
Medium Add Python to the image
Why: Teams build many languages.
What to do: Add python3 to the custom Dockerfile.
- Edit Dockerfile.
- Rebuild.
- docker exec jenkins python3 --version
Check: Python prints its version.
Hard Upgrade safely
Why: Upgrades must be planned.
What to do: Upgrade the VM Jenkins to the newest LTS after a backup.
- Back up /var/lib/jenkins.
- apt-get install --only-upgrade jenkins.
- Check jobs still run.
Check: Same jobs, newer version.
Easy Say installing Jenkins LTS in two lines
Why: If you can say it simply, you understand it. Juniors and interviewers want the short version first.
What to do: Write two short lines about installing Jenkins LTS for a fresher who knows only Linux basics.
- Write what problem it solves.
- Write the one command or menu you use for it.
- Read it aloud to a friend.
Check: A fresher understands it without asking a question.
Easy Start a fresh lab Jenkins
Why: Practice needs a throwaway Jenkins. If you break it, you delete it and start again.
What to do: Run Jenkins LTS in Docker with a named volume.
- docker volume create jenkins_home
- docker run -d --name jenkins -p 8080:8080 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17
- docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
Check: The Jenkins unlock page opens on localhost:8080.
Medium Break it on purpose
Why: You must know the red message by face. During an outage there is no time to read slowly.
What to do: Cause one error from the "When it is red" part of this lesson and fix it.
- Follow the error section.
- Copy the exact message into your notes.
- Write the fix in one line.
Check: You fixed it using only the steps, without searching the web.
Medium Write a one-page runbook
Why: At 2 a.m. nobody remembers where a file lives. A short page saves the on-call person.
What to do: Write a runbook page for this lesson.
- Title, when to use, exact command, how to check, how to undo.
Check: A teammate can follow it alone.
Medium Repeat it on a cloud VM
Why: A laptop is not a server. Real Jenkins runs on EC2 or a company VM.
What to do: Do the main steps of this lesson again on a small Ubuntu 22.04 EC2 instance.
- Launch t3.small with 20 GB disk.
- Open port 22 only to your IP.
- Repeat the steps and compare the output.
Check: Same green output on the VM as on your laptop.
Hard Explain it like an interview
Why: Interviewers want real stories, not definitions.
What to do: Record a 60 second answer about this lesson.
- Say the problem, the command you ran, and one error you hit.
Check: Your answer has a real command and a real error message.
Hard Draw the flow top to bottom
Why: A drawing shows who talks to whom and in what order.
What to do: Draw this lesson as boxes from top to bottom.
- Start at the developer push, go through the controller and agent, end at the result.
Check: Each box matches a real thing you saw on screen.
Homework: try at home
Try at home
On a t3.small Ubuntu 22.04 EC2 instance, run install-jenkins.sh, open port 8080 only to your IP, finish the wizard, then stop the instance. Write down the exact Jenkins and Java versions you got.
Recap
- Use the official debian-stable repository with the current key.
- Jenkins LTS needs Java 17 or 21.
- systemctl and journalctl tell you why it does not start.
- A custom image adds tools like Node.js while keeping the official base.
- Never run the Jenkins process as root.
FAQ
LTS or weekly?
LTS for anything real. Weekly gets new features first but changes every week.
Is the WAR file install fine?
It works, but packages and Docker handle services and upgrades for you.
Can I run Jenkins on Windows?
Yes, there is an MSI installer, but most companies run Linux controllers.
How much RAM?
2 GB for a lab, 8 GB or more for a team controller.
Interview questions
-
How do you install Jenkins on Ubuntu?
Install Java 17, add the pkg.jenkins.io debian-stable key and repo, apt install jenkins, enable with systemd, open 8080.
-
Jenkins will not start after an OS update. What do you check?
journalctl -u jenkins, Java version, disk space, and port 8080 conflicts.
-
Why build a custom Jenkins image?
To bake in tools like Node or Docker CLI and fixed plugins, so every restart is the same.
Quick quiz
Q1. Which repository line is LTS?
pkg.jenkins.io/debian-stable.
Q2. Which Java versions does current LTS support?
17 and 21.
Q3. Where is JENKINS_HOME for the apt install?
/var/lib/jenkins.
Q4. Which command shows Jenkins service logs?
journalctl -u jenkins.
Samajla ka?
Revision card
Interview card