|

Jenkins CI/CD (1/11): Prerequisites and Mental Model

← Previous Jenkins CI/CD (1/11) Next →

Summary: Understand what Jenkins is, how its controller/agent architecture works, and verify that a build agent has every tool the rest of this series requires — Python, Docker, Git, and network access.

Example Values Used in This Tutorial

KeyValue
Jenkins URLhttp://localhost:8080
Jenkins version2.462+ (LTS)
Python version3.12
Docker version27.x
Docker Composev2 (docker compose)
OS targetUbuntu 24.04 LTS

0. Prerequisites

  • An Ubuntu 24.04 LTS machine (physical, VM, or cloud instance) with sudo access
  • Internet connectivity to pull packages and Docker images
  • A Jenkins controller already installed and reachable at http://localhost:8080 (or your chosen URL)

Note: This tutorial focuses on verifying and preparing the build agent. Jenkins controller installation is outside the scope of this series — the official LTS installer or the Docker image both work.


1. What Jenkins Is and Why “Pipeline as Code” Matters

Jenkins is an open-source automation server. It listens for triggers — a Git push, a schedule, a manual click — and runs a sequence of steps in response. Those steps typically build your code, run tests, and deploy artifacts.

Older Jenkins setups stored job configuration in the web UI. Every change was a manual click, and there was no version history. Pipeline as code fixes that. You define your entire build, test, and deploy pipeline in a file called a Jenkinsfile, commit it alongside your application code, and let Jenkins read it directly from the repository.

This gives you three things you did not have before:

  • Version control — the pipeline evolves with the code it builds
  • Code review — pipeline changes go through the same pull-request process as application changes
  • Reproducibility — any commit carries the exact pipeline definition that was used to build it

Every tutorial in this series uses a declarative Jenkinsfile stored in the project repository.


2. Controller vs Agent — the Mental Model

Jenkins uses a controller/agent architecture. Understanding the split is essential before you write a single pipeline.

The controller is the central server. It hosts the web UI, stores job definitions, manages credentials, schedules builds, and records results. It does not run your build commands.

An agent (sometimes called a “node”) is a machine that actually executes the pipeline steps. The controller connects to agents over SSH or via a JNLP launcher, assigns work, and collects the results.

ComponentResponsibility
ControllerSchedule builds, serve UI, store logs and credentials
AgentExecute shell commands, run tests, build Docker images

Why does this matter? When your pipeline calls sh 'python -m pytest', that command runs on the agent, not on the controller. Every tool you need — Python, Docker, Git — must be installed on the agent. The controller does not need them.

Tip: In small setups, the controller can also act as an agent (the “built-in node”). That is fine for learning, but production workloads should always use dedicated agents so the controller stays responsive.


3. Workspaces — Where Builds Happen

Every time Jenkins runs a pipeline on an agent, it assigns a workspace — a directory on the agent’s filesystem where your repository is checked out and your commands execute.

The default path looks like this:

/var/lib/jenkins/workspace/<job-name>Code language: Shell Session (shell)

Key facts about workspaces:

  • Workspaces are persistent by default. Jenkins does not automatically delete them after a build finishes. Files from the previous run are still there when the next run starts.
  • If you run parallel builds of the same job, Jenkins appends @2, @3, etc. to create separate workspace directories.
  • A “clean workspace” strategy — deleting everything at the start of each build — avoids subtle bugs caused by leftover files. You will see this pattern throughout the series.

Warning: Stale workspace files are one of the most common causes of “works on the second run but not the first” bugs. Always design pipelines that either clean the workspace or tolerate leftover files.


4. The Jenkinsfile — Pipeline Definition in Your Repo

A Jenkinsfile is a Groovy-based script that lives in the root of your repository. Jenkins reads it, parses the stages, and executes them on the assigned agent.

Here is the minimal skeleton you will build on throughout this series:

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'echo "Building..."'
            }
        }
        stage('Test') {
            steps {
                sh 'echo "Testing..."'
            }
        }
        stage('Deploy') {
            steps {
                sh 'echo "Deploying..."'
            }
        }
    }
}Code language: Groovy (groovy)
  • pipeline — the top-level block that wraps everything
  • agent any — tells Jenkins to run this pipeline on any available agent
  • stages — a sequence of named stages that execute in order
  • steps — the actual commands inside each stage

You do not need to memorize this now. Every tutorial in the series adds to this skeleton one piece at a time.


5. Agent Requirements Checklist

The rest of this series requires five tools on the build agent. Verify each one now.

5.1 Python 3.12+

python3 --versionCode language: Shell Session (shell)
Python 3.12.3Code language: Shell Session (shell)

The exact patch version does not matter as long as the minor version is 3.12 or higher.

5.2 pip and venv

python3 -m pip --versionCode language: Shell Session (shell)
pip 24.0 from /usr/lib/python3/dist-packages/pip (python 3.12)Code language: Shell Session (shell)
python3 -m venv --help | head -1Code language: Shell Session (shell)
usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]Code language: Shell Session (shell)

If venv is missing, install it:

sudo apt-get update && sudo apt-get install -y python3-venvCode language: Shell Session (shell)

5.3 Docker Engine

docker --versionCode language: Shell Session (shell)
Docker version 27.3.1, build ce12230Code language: Shell Session (shell)

Verify the daemon is running:

sudo systemctl is-active dockerCode language: Shell Session (shell)
activeCode language: Shell Session (shell)

5.4 Docker Compose v2

This series uses the Compose v2 plugin (docker compose), not the legacy standalone binary (docker-compose).

docker compose versionCode language: Shell Session (shell)
Docker Compose version v2.29.2Code language: Shell Session (shell)

Warning: If docker compose returns “command not found” but docker-compose works, you have the legacy v1 binary. Install the v2 plugin with sudo apt-get install docker-compose-plugin.

5.5 Git

git --versionCode language: Shell Session (shell)
git version 2.43.0Code language: Shell Session (shell)

5.6 Network Access

Confirm the agent can reach Docker Hub:

docker pull hello-worldCode language: Shell Session (shell)
Using default tag: latest
latest: Pulling from library/hello-world
Status: Image is up to date for hello-world:latestCode language: Shell Session (shell)

If this fails behind a corporate proxy, configure Docker’s proxy settings in /etc/docker/daemon.json or via systemd environment overrides before continuing.

5.7 Jenkins Plugins Used in This Series

The tutorials assume a Jenkins LTS 2.462+ controller with the following plugins installed. Most ship with the suggested plugins bundle, but verify they are present before you start.

PluginJenkins IDFirst used inPurpose
Pipelineworkflow-aggregatorPart 3Declarative Jenkinsfile support
JUnitjunitPart 4junit step — parse test results
Workspace Cleanupws-cleanupPart 8cleanWs() step — wipe workspace
GitgitPart 3SCM checkout from Git repositories
Docker Pipelinedocker-workflowPart 9 (Pattern C only)agent { docker { ... } } syntax

Tip: You can install all of these at once from Manage Jenkins > Plugins > Available plugins. Later tutorials reference specific plugins when they introduce new steps — this table is the central reference so you can install everything up front.


6. Adding Your User to the Docker Group

By default, Docker commands require sudo. Jenkins agents typically run as a non-root user (often jenkins). If that user cannot run docker without sudo, every Docker step in your pipeline will fail with a permission error.

Add the Jenkins agent user to the docker group:

sudo usermod -aG docker jenkinsCode language: Shell Session (shell)

The group change takes effect on the next login. To apply it immediately without logging out:

newgrp dockerCode language: Shell Session (shell)

Verify the user can run Docker without sudo:

docker info --format '{{.ServerVersion}}'Code language: Shell Session (shell)
27.3.1Code language: Shell Session (shell)

If this still fails, restart the Docker daemon and try again:

sudo systemctl restart dockerCode language: Shell Session (shell)

Warning: Adding a user to the docker group grants root-equivalent access to the Docker daemon. On shared machines, understand the security implications before doing this.


7. Common Failure Modes

These are the three problems you will hit most often in the early tutorials. Know them now so you can diagnose them fast later.

7.1 “Cannot Connect to the Docker Daemon”

ERROR: Cannot connect to the Docker daeCreate a highly detailed, high-resolution image showcasing a Jenkins CI/CD pipeline dashboard prominently displaying test results and JUnit graphs. The image should feature a computer screen or monitor with the Jenkins interface, emphasizing trend graphs, failure drill-downs, and an organized layout of test histories. Soft, ambient lighting should highlight the screen while maintaining a clean, tech-savvy atmosphere, representing modern development environments. The focus must be sharp, with intricate details of the interface elements and clearly legible text, capturing the essence of efficient test reporting.mon at unix:///var/run/docker.sockCode language: Shell Session (shell)

This means either the Docker daemon is not running or the current user does not have permission to access the socket.

  • Check the daemon: sudo systemctl status docker
  • Check group membership: groups jenkins — the output must include docker
  • If you just added the user to the group, restart the agent process so it picks up the new group membership

7.2 Stale Workspace Files

A previous build left behind compiled files, old virtualenvs, or cached test results. The next build picks them up and either passes when it should fail or fails with a confusing error.

  • Fix: add a “clean workspace” step at the start of your pipeline
  • In declarative pipelines, use cleanWs() from the Workspace Cleanup plugin or deleteDir() in a pre-build step

7.3 Port Collisions

Two builds run at the same time and both try to bind port 5432 (or 8000, or any other fixed port). The second build fails with “address already in use.”

  • Fix: use dynamic ports or let Docker assign random host ports
  • In Docker Compose files, omit the host port (- "5432" instead of - "5432:5432") so Docker picks an available one
  • This series handles port management explicitly starting in the Docker Compose tutorial

8. Full Verification Script

Run this script on your build agent to verify everything at once. Every check must print OK.

#!/usr/bin/env bash
set -euo pipefail

echo "=== Agent Readiness Check ==="

echo -n "Python 3.12+ ... "
python3 -c "import sys; assert sys.version_info >= (3,12), f'Need 3.12+, got {sys.version}'" && echo "OK"

echo -n "pip ............ "
python3 -m pip --version > /dev/null 2>&1 && echo "OK"

echo -n "venv ........... "
python3 -m venv --help > /dev/null 2>&1 && echo "OK"

echo -n "Docker Engine .. "
docker version --format '{{.Server.Version}}' > /dev/null 2>&1 && echo "OK"

echo -n "Docker Compose . "
docker compose version > /dev/null 2>&1 && echo "OK"

echo -n "Git ............ "
git --version > /dev/null 2>&1 && echo "OK"

echo -n "Docker Hub ..... "
docker manifest inspect hello-world:latest > /dev/null 2>&1 && echo "OK"

echo ""
echo "All checks passed. This agent is ready."Code language: Shell Session (shell)

Save it as agent-check.sh and run it:

chmod +x agent-check.sh
./agent-check.shCode language: Shell Session (shell)
=== Agent Readiness Check ===
Python 3.12+ ... OK
pip ............ OK
venv ........... OK
Docker Engine .. OK
Docker Compose . OK
Git ............ OK
Docker Hub ..... OK

All checks passed. This agent is ready.Code language: Shell Session (shell)

If any line fails, go back to the relevant section above and resolve the issue before moving on to Part 2.


Summary

You now have two things: a mental model of how Jenkins works and a verified build agent.

  • Jenkins automates builds by reading a Jenkinsfile from your repository — this is “pipeline as code”
  • The controller schedules work; agents execute it — every tool must be installed on the agent, not the controller
  • Workspaces persist between builds — design pipelines that clean up or tolerate leftover files
  • Five tools are required on the agent — Python 3.12+, pip/venv, Docker 27.x, Docker Compose v2, and Git
  • Docker group membership is required for the Jenkins user to run containers without sudo
  • Three common failure modes — Docker permission errors, stale workspaces, and port collisions — account for most early-stage debugging

In Part 2, you will create the Python project that the pipeline builds and write your first Jenkinsfile.

Similar Posts

Leave a Reply