How to build a CI/CD Pipeline for Android with Jenkins and Docker— Part 2

Jorge Luis Castro Medina
5 min readOct 17, 2023


Today, we will continue building our continuous integration system using Jenkins and Docker. In this part of the tutorial, we’ll make some changes to enhance the build process and improve the initialization of the Jenkins container. If you want to learn how to set up Jenkins with Docker, you can refer to Part 1.

Let’s get started! 🚀

First and foremost, we need to simplify the process of building the Jenkins image. To achieve this, we’ll create a dedicated folder to store our configuration files. Create a folder named jenkins and choose a name that suits your preferences.

mkdir jenkins

Inside of the jenkins folder, you must create a Dockerfile with the following instructions:

FROM jenkins/jenkins
USER root

# Update the package list
RUN apt-get update

RUN apt-get install -y ca-certificates curl gnupg

# Install Docker plugin
RUN jenkins-plugin-cli --plugins docker-workflow:<version>

# Install Docker
RUN install -m 0755 -d /etc/apt/keyrings
RUN curl -fsSL | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
RUN chmod a+r /etc/apt/keyrings/docker.gpg

# Add the Docker repository to Apt sources
RUN echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

# To install the latest version
RUN apt-get install -y docker-ce docker-ce-cli docker-buildx-plugin docker-compose-plugin

USER Jenkins

Docker can build images automatically by reading the instructions from a Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. This page describes the commands you can use in a Dockerfile.

Dockerfile reference

I will now provide a brief explanation of each section of the script:

  • FROM jenkins/jenkins: This instruction specifies the base image for the new image. The Jenkins base image contains all the files and dependencies needed to run Jenkins.
  • USER root: This instruction sets the default user of the container to root. This is necessary to install the Docker plugin and Docker.
  • RUN apt-get update: This instruction updates the package list.
  • RUN apt-get install -y ca-certificates curl gnupg: This instruction Installs the ca-certificates, curl, and gnupg packages. These packages are needed to install the Docker plugin and Docker.
  • RUN jenkins-plugin-cli -plugins docker-workflow:<version>: This instruction installs the Docker plugin. The version of the plugin is specified as an argument. You can check the versions here.
  • RUN install -m 0755 -d /etc/apt/keyrings: This instruction creates the /etc/apt/keyrings directory, which will be used to store the Docker GPG key.
  • RUN curl -fsSL | gpg -dearmor -o /etc/apt/keyrings/docker.gpg: This instruction downloads the Docker GPG key and saves it to the /etc/apt/keyrings/docker.gpg file.
  • RUN chmod a+r /etc/apt/keyrings/docker.gpg: This instruction makes the Docker GPG key accessible to all users.
  • RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null: This instruction adds the Docker repository to the Apt sources list.
  • RUN apt-get install -y docker-ce docker-ce-cli docker-buildx-plugin docker-compose-plugin: This instruction installs Docker, Docker CLI, containerd, Docker Buildx, and Docker Compose.
  • USER jenkins: This instruction sets the default user of the container to Jenkins.

Now, the next step will be to create a docker-compose.yml file in the same directory where we created the Dockerfile, and within it, we will add the following instructions.

version: '3.8'
image: "jenkins/docker"
container_name: "jenkins"
build: .
user: root
- 8080:8080
- 50000:50000
- ~/jenkins_home/jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock

docker-compose file description:

  • services: This section defines the services that will be managed by Docker Compose.
  • jenkins: This is the name of the service, which represents the Jenkins container.
  • image: “jenkins/docker”: This line specifies the Docker image that will be used for the Jenkins container.
  • container_name: “jenkins”: This sets the name of the container to jenkins.
  • build: .: This line tells Docker to build the container from the current directory (the one containing the docker-compose.yml file). However, it’s important to note that in this configuration, it seems like a pre-built image is used.
  • user: root: The Jenkins container is set to run as the root user.
  • port: This section specifies port mappings for the container. It maps port 8080 from the host to port 8080 on the container and port 50000 from the host to port 50000 on the container. This is essential for accessing the Jenkins web interface.
  • volumes: This part defines the volumes that will be mounted into the container. It binds the local directory ~/jenkins_home/jenkins_home to the container's /var/jenkins_home, which is where Jenkins stores its configuration and data. It also binds /var/run/docker.sock from the host to /var/run/docker.sock in the container, which allows Jenkins to interact with the host's Docker daemon.

It’s time to put everything into action. ⏰💪😄

# Build the image
docker compose build

# Start container
docker compose up -d

# Stop container
docker compose down

If you already have the image ready, you just need to run🏃‍♂️ your container with docker compose up 💻🐳

📚 Sources

Other articles in this series

  • How to build a CI/CD Pipeline for Android with Jenkins and Docker — Part 2— you are here

If you like my content and want to support my work, you can give me a cup of coffee ☕️ 🥰

Follow me in



Jorge Luis Castro Medina

I'm a Software Engineer passionate about mobile technologies, and I like everything related to software design and architecture