Skip to main content
Jenkins Pipeline
CHAPTER 11

Docker Integration with Jenkins

Updated: May 15, 2026
25 min read

# CHAPTER 11

Docker Integration with Jenkins

1. Introduction

If you are building a PHP app today, a Node.js app tomorrow, and a Python app next week, installing all those different languages and their conflicting versions directly onto your Jenkins server will turn it into a chaotic mess (known as "Dependency Hell"). The modern solution is Docker. By integrating Docker with Jenkins, we can run our pipelines inside clean, isolated, disposable containers. Furthermore, the final output of our pipeline is no longer a .zip file, but a fully containerized Docker image ready for deployment. In this chapter, we will master the Jenkins Docker Pipeline plugin.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the benefits of using Docker containers as Jenkins Build Agents.
  • Configure a declarative pipeline to execute steps inside a specific Docker container.
  • Use Jenkins to build a custom Docker image from a Dockerfile.
  • Understand how to push built images to a Docker Registry (like Docker Hub).

3. Beginner-Friendly Explanation

Imagine a master chef (Jenkins) who needs to cook three different cuisines.
  • The Old Way: The chef installs a pizza oven, a sushi rolling station, and a taco press all in the same tiny kitchen. It's crowded, messy, and the flavors mix.
  • The Docker Way: The chef has a magical button. When they need to make sushi, they press the button, and a spotless, perfectly equipped "Sushi Kitchen" (A Docker Container) appears. The chef makes the sushi, and when they are done, the kitchen vanishes into thin air. Tomorrow, they press the button for a "Pizza Kitchen."

Docker allows Jenkins to conjure up perfectly clean, temporary environments to run your code, keeping the main Jenkins server perfectly clean.

4. Running Pipelines Inside Docker (Agents)

In previous chapters, we used agent any at the top of our Jenkinsfile. This told Jenkins to run the script directly on the host server. Now, we will change the agent. We will tell Jenkins to download a Docker image (e.g., node:18), start the container, put our source code inside it, and run our tests *inside* the container.
groovy
123456789101112131415
pipeline {
    // Instead of 'any', we specify a Docker image!
    agent {
        docker { image 'node:18-alpine' }
    }
    stages {
        stage('Test') {
            steps {
                // This command runs INSIDE the Node.js container!
                sh 'npm install'
                sh 'npm test'
            }
        }
    }
}

*When the pipeline finishes, Jenkins automatically deletes the Node.js container. Your Jenkins server never needed to have Node.js installed!*

5. Building and Pushing Docker Images

Often, the final goal of a CI/CD pipeline is to package your application into its own Docker image, so it can be deployed to a server or Kubernetes cluster.

To do this, you use standard Docker commands in your sh steps, assuming your Jenkins server has Docker installed on the host.

6. Mini Project: Build a Docker Image Automatically

Let's build a pipeline that compiles code and packages it into a Docker image. *(Prerequisite: The Jenkins server must have Docker installed and the "Docker Pipeline" plugin configured).*

Step-by-Step Pipeline Concept:

groovy
12345678910111213141516171819202122232425262728293031
pipeline {
    agent any
    environment {
        // Define the name of our final image
        IMAGE_NAME = 'my-company/my-php-app'
        IMAGE_TAG = "v${env.BUILD_NUMBER}" // Uses the Jenkins build number (e.g., v42)
    }
    stages {
        stage('Build Docker Image') {
            steps {
                echo 'Building the Docker Image...'
                // Jenkins runs the docker build command, reading the Dockerfile in your repo
                sh "docker build -t ${IMAGE_NAME}:${IMAGE_TAG} ."
            }
        }
        stage('Push to Registry') {
            steps {
                echo 'Pushing image to Docker Hub...'
                // We will learn how to handle the password securely in Chapter 14!
                // sh 'docker login -u myuser -p mypassword'
                sh "docker push ${IMAGE_NAME}:${IMAGE_TAG}"
            }
        }
    }
    post {
        always {
            // Clean up the heavy image from the Jenkins hard drive
            sh "docker rmi ${IMAGE_NAME}:${IMAGE_TAG} || true"
        }
    }
}

7. Real-World Scenarios

A company had a monolithic Jenkins server with PHP 5.6, PHP 7.4, and PHP 8.1 all installed globally. A developer needed to test a legacy app and accidentally upgraded the global PHP 5.6 environment variables to 8.1. Every single legacy pipeline in the company immediately crashed, halting all deployments for a day. The DevSecOps team rebuilt the architecture: they uninstalled all languages from the Jenkins server. From then on, every Jenkinsfile had to declare a specific Docker agent (e.g., agent { docker { image 'php:7.4-cli' } }). Because every build ran in an isolated container, dependency conflicts were mathematically eliminated forever.

8. Best Practices

  • Use Specific Tags, Not 'latest': When defining a Docker agent (e.g., node:latest), your build might pass today, but fail tomorrow if the Node.js team releases a new version that breaks your code. Always lock your agent to a specific, immutable version tag (e.g., node:18.16.0-alpine).

9. Security Recommendations

  • Docker Socket Security: To allow Jenkins to run docker build commands, administrators often map the host's /var/run/docker.sock file into the Jenkins container. This is highly dangerous. Anyone who can execute a shell script in Jenkins has root access to the host server. In enterprise environments, prefer secure alternatives like "Kaniko" or "Podman" for rootless image building.

10. Troubleshooting Tips

  • "Docker command not found": If your pipeline fails on sh 'docker build ...', it means the Jenkins agent you are currently running on does not have the Docker executable installed. You must install Docker CLI on your Jenkins worker nodes.

11. Exercises

  1. 1. Explain the architectural benefit of using agent { docker { image 'php:8.1' } } instead of installing PHP 8.1 directly onto the Jenkins host server.
  1. 2. What is the purpose of the Jenkins ${env.BUILD_NUMBER} variable when tagging a Docker image?

12. FAQs

Q: Can I use different Docker containers for different stages? A: Yes! You can put the agent { docker { ... } } block inside a specific stage instead of at the top of the pipeline. Stage 1 could run in a Node container to compile frontend assets, and Stage 2 could run in a PHP container to run backend tests.

13. Interview Questions

  • Q: Describe the "Docker out of Docker" (DooD) pattern commonly used in Jenkins. What are the security implications of binding the host's Docker socket to the Jenkins container?
  • Q: A pipeline successfully builds a 1GB Docker image, pushes it to a registry, and completes. However, the Jenkins server runs out of disk space after 50 builds. Identify the missing architectural step in the Jenkinsfile and how to fix it.

14. Summary

In Chapter 11, we solved the "Dependency Hell" problem by integrating Docker with Jenkins. We learned how to use Docker containers as ephemeral, highly controlled build agents, ensuring our pipelines run in pristine environments every single time. We also wrote the commands necessary to build our applications into portable Docker images and push them to external registries, preparing them for the final stage of the CI/CD journey: Deployment.

15. Next Chapter Recommendation

Our code is tested and packaged into a neat, deployable artifact. Now, we must push it to the live internet. Proceed to Chapter 12: Deploying Applications with Jenkins.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·