Jenkins Hands-on Exercises — Build the Assembly Line
Time to stop reading and start doing. These exercises require Jenkins running locally. The easiest way is Docker:
docker run -d --name jenkins -p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
Open http://localhost:8080 and follow the setup wizard.
Copy each command, run it, and compare what you see with the expected output below it.
Exercise 0 · Setup — Open the Factory
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Paste this into the Jenkins setup wizard at http://localhost:8080. Install the suggested plugins.
docker exec jenkins sh -c "curl -LO https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl && chmod +x kubectl && mv kubectl /usr/local/bin/"
The Jenkins container needs the same tools as your local machine (kubectl, docker, node). Install them inside the container.
Exercise 1 · First Job — A Simple Assembly Line
- Click New Item → Enter
campus-library-build→ Select Pipeline → OK - Scroll to Pipeline section → Select Pipeline script
- Paste:
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building Campus Library...'
sh 'echo "Build complete!"'
}
}
stage('Test') {
steps {
echo 'Running tests...'
sh 'echo "All tests passed!"'
}
}
}
}
- Click Save → Build Now
Check the Console Output to see your pipeline run.
echo prints a message. sh runs a shell command. Both are "steps" within a stage.
Exercise 2 · Build a Real App
mkdir jenkins-exercise
cd jenkins-exercise
cat > package.json << 'EOF'
{
"name": "campus-library",
"version": "1.0.0",
"scripts": {
"test": "echo \"Tests passed!\" && exit 0",
"build": "echo \"Build complete!\""
}
}
EOF
Push this to a Git repo (GitHub, GitLab, etc.).
Create a new Pipeline job pointing to your repo:
- New Item →
campus-library-ci→ Pipeline - Pipeline → Git → Enter your repo URL
- Save → Build Now
When Jenkins is connected to Git, it pulls the code and looks for Jenkinsfile at the repo root.
Exercise 3 · Add Docker Build
pipeline {
agent { docker { image 'node:20-alpine' } }
environment {
DOCKER_IMAGE = "riya/campus-library:${env.BUILD_NUMBER}"
}
stages {
stage('Install') {
steps {
sh 'npm install || echo "No dependencies"'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build Image') {
steps {
sh "docker build -t ${DOCKER_IMAGE} ."
}
}
stage('Push Image') {
steps {
withCredentials([usernamePassword(
credentialsId: 'dockerhub',
usernameVariable: 'USER',
passwordVariable: 'PASS'
)]) {
sh "echo \$PASS | docker login -u \$USER --password-stdin"
sh "docker push ${DOCKER_IMAGE}"
}
}
}
}
}
withCredentials injects credentials as environment variables. The credentials must be stored in Jenkins first (Manage Jenkins → Credentials).
Exercise 4 · Conditional Deployment
pipeline {
agent any
stages {
stage('Build') {
steps { sh 'echo "Building..."' }
}
stage('Deploy to Staging') {
when { branch 'develop' }
steps { sh 'echo "Deployed to staging"' }
}
stage('Deploy to Production') {
when { branch 'main' }
input { message 'Deploy to production?' }
steps { sh 'echo "Deployed to production"' }
}
}
}
Create branches develop and main and push. Watch how Jenkins runs different stages for each branch.
when { branch 'main' } ensures production deployments only happen from the main branch. input adds a manual approval gate.
Exercise 5 · Post Actions — Notifications
pipeline {
agent any
stages {
stage('Build') {
steps { sh 'echo "Building..."' }
}
stage('Test') {
steps {
sh 'echo "Testing..."'
sh 'exit 1' // Simulate failure
}
}
}
post {
always {
sh 'echo "Cleaning up..."'
}
success {
sh 'echo "Build succeeded!"'
}
failure {
sh 'echo "Build failed! Sending alert..."'
}
}
}
post.always runs regardless of result — use it for cleanup. post.failure runs only on failure — use it for alerts.
Exercise 6 · Cleanup
docker stop jenkins
docker rm jenkins
docker volume rm jenkins_home
Remove Jenkins volumes after exercises to free disk space. In production, always back up jenkins_home.