How to Set Up Jenkins in Docker with Docker-in-Docker (DinD) on Ubuntu ?


What Is Jenkins with Docker-in-Docker (DinD)?
Jenkins with Docker-in-Docker (DinD) is a setup where:
Jenkins itself runs inside a Docker container
Inside that Jenkins container, your pipelines can also run Docker commands
This is possible thanks to a second container: Docker-in-Docker, or DinD
🔁 Basically:
A Jenkins container talks to a Docker daemon inside another container, so it can build/run Docker images from within a pipeline.
Why Use Docker-in-Docker (DinD) with Jenkins?
Here are the key reasons for using DinD in this setup:
No need to modify the host system
You don’t have to install Jenkins directly on the host and add the Jenkins user to thedocker
group on your machine.Isolated and secure environment
DinD runs in its own container, providing better isolation and reducing the risk of Jenkins directly accessing the host Docker daemon.Jenkins can run Docker commands inside the container
By connecting Jenkins to the DinD container, it can executedocker build
,docker run
, etc., inside its own CI pipelines.Reusable and portable setup
This containerized setup can be replicated on any machine — perfect for testing, learning, or CI/CD automation.Supports multiple Jenkins agents
You can scale Jenkins with multiple agents, each connecting to its own DinD container — useful for parallel builds or larger workflows.Clean environment
Every time you restart the containers, you start with a fresh and controlled environment — no leftover images or containers from previous builds (unless persisted intentionally).
What Is Docker-in-Docker (DinD)?
Docker-in-Docker (DinD) means running the Docker Engine inside a container. It allows you to run Docker commands like docker build
, docker run
, or docker push
from within another container.
In this Jenkins setup:
Jenkins uses Docker CLI to talk to a DinD container
The DinD container runs a real Docker daemon, isolated from your host
Why Jenkins inside Docker?
Easy to isolate and run Jenkins as a container
Quick to deploy, clean to remove
No need to install Jenkins directly on your host system.
Prerequisites
Make sure you have:
Ubuntu 20.04+ or 24.04 LTS
Docker installed (
sudo apt install
docker.io
)A user added to Docker group (
sudo usermod -aG docker $USER
)Activate the new group membership in your current shell session without logging out and back (
newgrp docker
)
Step 1 : Create a bridge network in Docker using the following command
docker network create jenkins
Step 2 : Download and run the docker:dind
Docker image using the following command
docker run \
--name jenkins-docker \
--detach \
--privileged \
--network jenkins \
--network-alias docker \
--env DOCKER_TLS_CERTDIR=/certs \
--volume jenkins-docker-certs:/certs/client \
--volume jenkins-data:/var/jenkins_home \
--publish 2376:2376 \
docker:dind \
--storage-driver overlay2
Breakdown:
--name jenkins-docker
: Names the containerjenkins-docker
.--detach
: Runs the container in the background (detached mode).--privileged
: Grants extended privileges (required for Docker-in-Docker).--network jenkins
: Connects to thejenkins
Docker network.--network-alias docker
: Creates a network aliasdocker
(used by Jenkins to access Docker).--env DOCKER_TLS_CERTDIR=/certs
: Enables TLS and stores certificates in/certs
.--volume jenkins-docker-certs:/certs/client
: Mounts volume for TLS client certs.--volume jenkins-data:/var/jenkins_home
: Mounts Jenkins home directory to persist data.--publish 2376:2376
: Exposes Docker daemon over port 2376 (TLS-secured).docker:dind
: Uses the official Docker-in-Docker image.--storage-driver overlay2
: Sets the Docker storage driver tooverlay2
for better performance and layering.
Step 3 : Create a custom Jenkins Docker Image
create a Dockerfile with the following content:
FROM jenkins/jenkins:2.504.2-jdk21
USER root
RUN apt-get update && apt-get install -y lsb-release ca-certificates curl && \
install -m 0755 -d /etc/apt/keyrings && \
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && \
chmod a+r /etc/apt/keyrings/docker.asc && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null && \
apt-get update && apt-get install -y docker-ce-cli && \
apt-get clean && rm -rf /var/lib/apt/lists/*
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow json-path-api"
Step 4 : Build the Image by assigning a custom name
docker build -t myjenkins-blueocean:2.504.2-1 .
Step 5 : Run the Jenkins image as a container
docker run \
--name jenkins-blueocean \
--restart=on-failure \
--detach \
--network jenkins \
--env DOCKER_HOST=tcp://docker:2376 \
--env DOCKER_CERT_PATH=/certs/client \
--env DOCKER_TLS_VERIFY=1 \
--publish 8080:8080 \
--publish 50000:50000 \
--volume jenkins-data:/var/jenkins_home \
--volume jenkins-docker-certs:/certs/client:ro \
myjenkins-blueocean:2.504.2-1
Breakdown:
--name jenkins-blueocean
: Names the containerjenkins-blueocean
.--restart=on-failure
: Automatically restarts the container if it crashes.--detach
: Runs the container in the background.--network jenkins
: Connects it to the same custom Docker network (jenkins
) as the Docker daemon.--env DOCKER_HOST=tcp://docker:2376
: Tells Jenkins where to find the Docker daemon (via the aliasdocker
).--env DOCKER_CERT_PATH=/certs/client
: Path to TLS client certs (read-only).--env DOCKER_TLS_VERIFY=1
: Enables TLS verification.--publish 8080:8080
: Exposes Jenkins web UI on port 8080.--publish 50000:50000
: Exposes the port for Jenkins agent communication.--volume jenkins-data:/var/jenkins_home
: Persists Jenkins configuration and job data.--volume jenkins-docker-certs:/certs/client:ro
: Mounts Docker TLS certs in read-only mode.myjenkins-blueocean:2.504.2-1
: Uses your custom-built Jenkins Blue Ocean image.
Step 6: Post-installation setup wizard
After downloading, installing and running Jenkins using one of the procedures above (except for installation with Jenkins Operator), the post-installation setup wizard begins.
This setup wizard takes you through a few quick "one-off" steps to unlock Jenkins, customize it with plugins and create the first administrator user through which you can continue accessing Jenkins.
Unlocking Jenkins
When you first access a new Jenkins controller, you are asked to unlock it using an automatically-generated password.
Browse to
http://localhost:8080
(or whichever port you configured for Jenkins when installing it) and wait until the Unlock Jenkins page appears.
Step 8 : Accessing the Docker container
Run the following command in bash to access the container
docker exec -it jenkins-blueocean bash
now run the following command to get the initial password
cat /var/jenkins_home/secrets/initialAdminPassword
Step 9: Install Suggested Plugins
This will install common plugins like Git, Pipeline, etc. You can always install more later.
Step 10: Create Admin User
Fill in the form to create your first Jenkins user and complete the setup.
keep the Jenkins URL as it is and click on save and finish.
Jenkins is ready
click on start using Jenkins.
Note
The Jenkins container uses persistent storage through Docker volumes. This means your Jenkins data (like jobs, plugins, configurations) will be saved even if the container stops or restarts.
If the Jenkins container stops, you can simply restart it using:
docker start jenkins-blueocean docker start jenkins-docker
And it will resume from where it left off — no data lost.
The jenkins-blueocean is the jenkins container
the jenkins-docker is the Docker-in-Docker (DinD) container.
In order for Jenkins to run Docker commands inside jobs, both the Jenkins container and the Docker-in-Docker (DinD) container must be running on the same Docker network.
Conclusion :
In this guide, you learned how to install and configure Jenkins on Ubuntu , giving you a solid foundation to start building CI/CD pipelines. Jenkins is a powerful tool that automates your build, test, and deployment workflows and setting it up properly is your first big step into the world of DevOps.
Whether you're just exploring automation or aiming to master continuous integration, Jenkins will be a core part of your DevOps toolkit.
#jenkins
#devops
#ubuntu
#cicd
#linux
#docker
#jenkins-dockers
Subscribe to my newsletter
Read articles from Arief Shaik directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Arief Shaik
Arief Shaik
I’m a passionate DevOps and cloud enthusiast with hands-on experience in building and automating modern infrastructure using tools like Docker, Terraform, Jenkins, and GitHub Actions. My core skill set includes Java, Python, shell scripting, and deploying containerized applications on Azure and AWS. I actively work on real-world projects involving CI/CD, infrastructure as code, cloud deployment, and Linux automation. Driven by curiosity and consistency, I enjoy turning complex problems into simple, automated solutions. I’m always exploring new technologies and looking to contribute to open-source projects and collaborate with the developer community.