Build a CI/CD Pipeline with Jenkins

Run Jenkins in Docker and build a multi-stage CI/CD pipeline.

Introduction

30 Second Summary

Every time a developer pushes code, someone needs to check it compiles, passes its tests, and gets shipped to users. Doing this manually is slow, error-prone, and boring. That's why professional teams automate it with a CI/CD pipeline.

In this project, you will build your first CI/CD pipeline using Jenkins, the most widely adopted open-source automation server. You'll run Jenkins inside a Docker container on your local machine and create a pipeline that automatically builds, tests, and deploys an application.

What You'll Build

A fully functional Jenkins pipeline running locally in Docker that executes Build, Test, and Deploy stages every time you push code to GitHub.

By the end of this project, you'll have:

  • A running Jenkins server inside Docker, accessible at http://localhost:8080.
  • A Declarative Pipeline with Build, Test, and Deploy stages that automates a simple application workflow.
  • A Jenkinsfile committed to a GitHub repository that triggers automated pipeline runs whenever code changes.
  • Secret Mission: Add a manual approval gate between staging and production deployment stages.

Are there any prerequisites?

You'll need a basic understanding of what version control (Git) is. No prior Jenkins or Docker experience is required.

Install Docker Desktop and Git

To build a CI/CD pipeline, you need two foundational tools on your machine.

Docker lets you run Jenkins inside a container without installing Java or configuring server software directly on Windows. Git connects your local code to GitHub so Jenkins can pull your pipeline definition automatically.

In this step, get ready to:
  • Install Docker Desktop and confirm it runs Linux containers.
  • Verify Docker works by running a test container.
  • Verify Git is installed and ready for use.
Download and install Docker Desktop

Docker Desktop bundles everything you need to run containers on Windows. It includes the Docker engine, CLI, and a graphical interface for managing containers.

  • Open your browser and navigate to the Docker Desktop for Windows install page:
  • Docker Desktop for Windows
  • Click the download button for Docker Desktop for Windows - x86_64.
  • Double-click Docker Desktop Installer.exe to run the installer.
  • When prompted, ensure the Use WSL 2 instead of Hyper-V option is selected (this is the default).
  • Follow the instructions on the installation wizard and click Close when installation completes.

What is Docker Desktop?

Docker Desktop is an application that lets you run lightweight, isolated environments called containers. Instead of installing Jenkins and Java directly on your machine, you run Jenkins inside a container that already has everything pre-configured.

This makes setup fast and cleanup trivial. When you are done with the project, you just delete the container.

  • Start Docker Desktop by pressing the Windows key, typing Docker, and pressing Enter.
  • Accept the Docker Subscription Service Agreement when prompted.
  • Wait for Docker Desktop to fully start. You will see the Docker whale icon appear in your system tray (bottom-right corner of your taskbar).

Why Linux Containers?

Docker Desktop on Windows defaults to Linux Containers mode. The Jenkins Docker image is a Linux container, so this default is exactly what you need. Do not switch to Windows Containers.

Verify Docker is working

With Docker Desktop running, you can use the Docker CLI in a terminal to confirm everything is set up correctly.

  • Open a terminal by pressing the Windows key, typing PowerShell, and pressing Enter.
  • Check your Docker version by running this command:
docker --version

✔️ I see a version number

You should see output like Docker version 27.x.x (your exact version may differ). Docker is installed and ready.

ⓧ I see an error or 'not recognized'

If your terminal does not recognize the docker command, try these fixes:

  • Make sure Docker Desktop is running. Look for the whale icon in your system tray.
  • Close your terminal and open a new one. Docker adds itself to your PATH during installation, but existing terminals do not pick up the change.
  • If the problem persists, restart your computer and try again.
  • Run a test container to confirm Docker can pull images and create containers:
docker run hello-world

You should see a message that starts with Hello from Docker! followed by a confirmation that your installation is working correctly.

Don't see the Hello from Docker message?

  • If you see a network timeout error, check that your internet connection is active. Docker needs to download the hello-world image from Docker Hub.
  • If you see a permissions error, make sure Docker Desktop has fully started (whale icon is stable, not animating).

Help me troubleshoot my Docker installation

Verify Git is installed

Git is the version control tool that lets you push code to GitHub. Jenkins will read your pipeline definition from a GitHub repository, so Git needs to be available on your machine.

  • In the same PowerShell terminal, check if Git is already installed by running:
git --version

✔️ I see a version number

You should see output like git version 2.x.x. Git is ready to use.

ⓧ Command not found

Git is not installed yet. Follow these steps to install it:

  • Open your browser and go to the official Git download page:
  • Git for Windows
  • Click the download link for the latest version. The installer will download automatically.
  • Run the installer and accept the default settings on each screen. Click Next through the wizard until installation completes.
  • Close your PowerShell terminal and open a new one (press the Windows key, type PowerShell, press Enter).
  • Run git --version again. You should now see a version number.

Git still not recognized after installing?

  • Make sure you closed and reopened your terminal after installation. Existing terminals do not pick up new PATH entries.
  • If you used a custom installation path, you may need to restart your computer for PATH changes to take effect.

Help me get Git working on my Windows machine

Your tools are installed and ready. Next up, you will launch Jenkins inside a Docker container and access it in your browser.

Launch Jenkins in Docker

Docker Desktop is installed and ready to go. Now it's time to get Jenkins up and running.

Normally, installing Jenkins means setting up Java, configuring environment variables, and managing system services. With Docker, you can skip all of that and launch a fully configured Jenkins server with a single command.

In this step, get ready to:
  • Create a Docker network and container for Jenkins.
  • Unlock Jenkins using the initial admin password.
  • Complete the Jenkins setup wizard and reach the dashboard.
Create the Jenkins network and container

Docker containers communicate over networks. You'll create a dedicated network for Jenkins, then start the Jenkins container connected to it.

  • Create the Docker network and start the Jenkins container by running these commands in your terminal:
docker network create jenkins
docker run --name jenkins --detach --publish 8080:8080 --publish 50000:50000 --volume jenkins-data:/var/jenkins_home --network jenkins jenkins/jenkins:lts-jdk21

What do these commands do?

  • docker network create jenkins creates an isolated network named jenkins for the container to communicate on.
  • --detach runs the container in the background so you can keep using your terminal.
  • --publish 8080:8080 maps port 8080 inside the container to port 8080 on your machine, so you can access Jenkins in your browser.
  • --volume jenkins-data:/var/jenkins_home saves all Jenkins data to a named volume, so your settings persist even if you stop the container.
  • jenkins/jenkins:lts-jdk21 is the official Jenkins Long Term Support image with Java 21 bundled inside.
  • Verify the container is running by running:
docker ps

You should see a row showing the jenkins container with a status of "Up" and ports 0.0.0.0:8080->8080/tcp listed.

Container not showing up?

  • Make sure Docker Desktop is running. Check for the Docker whale icon in your system tray.
  • If you see an error about port 8080 already in use, another application is using that port. Close it and try again.
  • Confirm Docker Desktop is set to run Linux Containers (this is the default). Jenkins does not provide a Windows container image.

Help me troubleshoot why my Jenkins Docker container isn't starting.

Retrieve the initial admin password

Jenkins generates a one-time admin password when it starts for the first time. You need this password to unlock the Jenkins web interface.

  • Retrieve the initial admin password by running this command:
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

You should see a long string of letters and numbers printed in your terminal (something like 2a4f8c6e12...). Copy this password.

What does this command do?

docker exec runs a command inside a running container. Here it reads the password file that Jenkins stored at /var/jenkins_home/secrets/initialAdminPassword during first boot.

Seeing "No such file or directory"?

Jenkins may still be starting up. Wait 30 seconds and try the command again. The container needs a moment to generate the password file on first launch.

Help me get the Jenkins initial admin password from my Docker container.

Unlock Jenkins and complete the setup wizard

Jenkins is now running inside the container and waiting for you to finish setting it up through the browser.

  • Open your browser and go to http://localhost:8080.
  • On the Unlock Jenkins page, paste the admin password you copied into the Administrator password field.
  • Click Continue.
  • On the Customize Jenkins page, click Install suggested plugins.

Why install suggested plugins?

Jenkins is highly modular. The suggested plugins bundle covers the most common use cases, including Git integration, pipeline support, and build tools. This saves you from manually hunting for each plugin later.

The plugins will take a minute or two to install. Once they finish, you'll see the Create First Admin User page.

  • Fill in a username, password, full name, and email address for your admin account.
  • Click Save and Continue.
  • On the Instance Configuration page, leave the Jenkins URL as http://localhost:8080/ and click Save and Finish.
  • Click Start using Jenkins.

You should now see the Jenkins dashboard with a "Welcome to Jenkins!" message. This is your automation command center.

Page not loading at localhost:8080?

  • Jenkins can take up to 60 seconds to fully start. Refresh the page after waiting.
  • Run docker ps to confirm the container is still running. If it exited, run docker start jenkins to bring it back up.

Help me access Jenkins in my browser on localhost:8080.

Your Jenkins server is live and ready to automate. Next up, you'll create a GitHub repository with a Jenkinsfile that defines your first pipeline.

Create a GitHub Repository with a Jenkinsfile

Your Jenkins server is up and ready to automate workflows. Now it needs something to automate.

In this step, you'll create a Jenkinsfile and store it in a GitHub repository. A Jenkinsfile is a text file that defines your entire pipeline as code. Jenkins reads this file to know exactly what stages to run, in what order, and what to do if something fails.

In this step, get ready to:
  • Create a public GitHub repository for your pipeline project.
  • Write a Declarative Pipeline with Build, Test, and Deploy stages.
  • Push your Jenkinsfile to GitHub so Jenkins can access it.
Create a GitHub repository and clone it

Jenkins needs a source code repository to pull your pipeline definition from. You'll create a new repository on GitHub and clone it to your local machine.

  • Open github.com in your browser and sign in to your account.
  • Click the + icon in the upper-right corner of the page.
  • Select New repository from the dropdown menu.
  • Enter jenkins-pipeline-demo as the repository name.
  • Select Public for the visibility setting.
  • Leave all other options at their defaults and click Create repository.

GitHub shows you a Quick Setup page with your repository URL. You'll use this URL to clone the repository.

  • Switch back to your terminal.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Clone your new repository by running this command:
git clone [[YOUR_REPO_URL="https://github.com/YOUR_USERNAME/jenkins-pipeline-demo.git"]]
  • Move into the cloned folder by running:
cd jenkins-pipeline-demo

Where do I find my repository URL?

On the Quick Setup page that appeared after you created the repo, look for the HTTPS URL. It looks like https://github.com/YOUR_USERNAME/jenkins-pipeline-demo.git. Click the clipboard icon next to it to copy.

  • Confirm you're in the right folder by running:
ls

You should see an empty directory (or just a README.md if you initialized with one).

Clone failed or permission denied?

Make sure you selected Public when creating the repository. Private repos require authentication credentials to clone.

Double check that the URL matches the one shown on your GitHub Quick Setup page. A typo in the username or repo name causes a "not found" error.

Help me troubleshoot my git clone error.

Create the Jenkinsfile

A Declarative Pipeline uses a structured format that breaks your automation into stages. Each stage represents a distinct phase of your software delivery process.

  • Open your jenkins-pipeline-demo folder in your code editor.
  • Create a new file named Jenkinsfile in the root of the folder (no file extension).
  • Copy the following pipeline code into Jenkinsfile:
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building the application...'
                sh 'echo "Compiling source code..."'
            }
        }
        stage('Test') {
            steps {
                echo 'Running tests...'
                sh 'echo "All 5 tests passed!"'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying to production...'
                sh 'echo "Application deployed successfully!"'
            }
        }
    }
    post {
        success {
            echo 'Pipeline completed successfully!'
        }
        failure {
            echo 'Pipeline failed. Check the logs for details.'
        }
    }
}

What does this pipeline do?

The pipeline block wraps your entire workflow. agent any tells Jenkins to run this pipeline on any available executor.

Inside stages, three phases run in sequence. Build compiles the code. Test runs automated checks. Deploy pushes the application to production.

The post block runs after all stages finish. It prints a success message if everything passed, or a failure message if any stage broke.

Why does the Jenkinsfile use sh instead of bat?

Even though your computer runs Windows, the Jenkins pipeline executes inside a Linux Docker container. The sh step runs shell commands on Linux agents.

The bat step is only for pipelines that run directly on a Windows machine. Since your Jenkins server lives inside the jenkins/jenkins:lts-jdk21 image (which is Linux-based), sh is correct.

  • Save Jenkinsfile.

Make sure the filename is exact

The file must be named exactly Jenkinsfile with a capital J and no file extension. Names like jenkinsfile, Jenkinsfile.groovy, or Jenkinsfile.txt will not be detected by Jenkins.

Jenkins isn't finding my Jenkinsfile. Help me fix the filename.

✔️ Awesome, I've got everything!

Great. Double check you've saved Jenkinsfile in the root of your jenkins-pipeline-demo folder.

ⓧ I'd like to double check the full code

Here is the complete Jenkinsfile for comparison:

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building the application...'
                sh 'echo "Compiling source code..."'
            }
        }
        stage('Test') {
            steps {
                echo 'Running tests...'
                sh 'echo "All 5 tests passed!"'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying to production...'
                sh 'echo "Application deployed successfully!"'
            }
        }
    }
    post {
        success {
            echo 'Pipeline completed successfully!'
        }
        failure {
            echo 'Pipeline failed. Check the logs for details.'
        }
    }
}
Commit and push the Jenkinsfile to GitHub

Your Jenkinsfile exists only on your local machine right now. You need to push it to GitHub so Jenkins can pull it from the repository later.

  • Switch back to your terminal.
  • Stage, commit, and push your Jenkinsfile by running these commands:
git add Jenkinsfile
git commit -m "Add initial Jenkinsfile with CI/CD pipeline"
git push origin main

What do these commands do?

git add Jenkinsfile stages the file for commit, telling Git you want to include it in the next snapshot.

git commit -m saves that snapshot with a descriptive message. git push origin main uploads the commit to your GitHub repository on the main branch.

  • Verify the push succeeded by refreshing your repository page on GitHub.

You should see Jenkinsfile listed in the file tree on your repository's main page.

Push rejected or authentication error?

If Git asks for credentials, you may need to set up a personal access token. GitHub no longer accepts passwords for command-line pushes.

If the push is rejected because the remote contains work you don't have locally, run git pull origin main first, then try pushing again.

Help me fix my git push authentication error.

Your pipeline definition is now stored in GitHub. Next up, you'll connect Jenkins to this repository and watch it execute your pipeline automatically.

Create and Run Your Pipeline in Jenkins

Your Jenkinsfile is committed to GitHub and ready to be picked up. Now it's time to point Jenkins at your repository so it can read and execute your pipeline automatically.

In this step, you'll create a Pipeline project inside Jenkins, connect it to your GitHub repository, and trigger the first build. You'll watch each stage execute in sequence and see the results visualized as green boxes.

In this step, get ready to:
  • Create a new Pipeline project in Jenkins.
  • Connect the pipeline to your GitHub repository.
  • Trigger the first build and verify all stages pass.
Create a new Pipeline project
  • In the Jenkins dashboard at http://localhost:8080, click New Item in the left sidebar.
  • Enter my-first-pipeline in the item name field.
  • Select Pipeline as the project type.
  • Click OK.

What is a Pipeline project?

A Pipeline project in Jenkins reads its build instructions from a Jenkinsfile instead of relying on manual GUI configuration. This approach is called Pipeline-as-Code.

Because the pipeline definition lives in your repository alongside your application code, any team member can review and update it through version control.

Connect the pipeline to your GitHub repository

Jenkins needs to know where your Jenkinsfile lives. You'll point it at your GitHub repository so it can pull the file on every build.

  • On the pipeline configuration page, scroll down to the Pipeline section.
  • Change the Definition dropdown to Pipeline script from SCM.
  • Select Git as the SCM.
  • Paste your GitHub repository URL into the Repository URL field.
  • Set the Branch Specifier to */main.
  • Click Save.

What does Pipeline script from SCM mean?

SCM stands for Source Code Management. This setting tells Jenkins to pull the Jenkinsfile directly from your Git repository instead of defining the pipeline inline through the Jenkins UI.

Any changes you push to GitHub will be picked up on the next build. This is why Pipeline-as-Code is powerful for teams.

Trigger your first build
  • Click Build Now in the left sidebar.
  • Wait a few seconds for the build to appear under Build History in the bottom-left corner.
  • Click the build number (#1) to open the build details.
  • Click Console Output in the left sidebar.

You should see each stage execute in sequence. Look for the echo messages from your Jenkinsfile: "Building the application...", "Running tests...", and "Deploying to production...".

  • Click the pipeline name (my-first-pipeline) in the breadcrumb at the top to return to the pipeline's main page.

The Stage View visualization shows each stage as a green box, confirming that Build, Test, and Deploy all passed successfully.

Build failing with a red indicator?

  • Check that your GitHub repository URL is correct and the repository is public. Jenkins needs to access it without credentials for a public repo.
  • Make sure your Jenkinsfile is on the main branch. If your repository uses a master branch instead, update the Branch Specifier to */master.
  • Open the Console Output and scroll to the bottom to find the specific error message. Syntax issues in the Jenkinsfile will be described there.

Why is my Jenkins pipeline build failing?

Your pipeline runs end to end with a single click. Next, you'll make it smarter by adding environment variables and an automatic trigger that detects new commits.

Enhance Your Pipeline with Environment Variables and Triggers

Your pipeline runs perfectly. Jenkins pulls the Jenkinsfile from GitHub and executes three stages automatically.

Right now, though, every string in your pipeline is hardcoded. If you rename your app or bump a version number, you'd have to hunt through every stage to update it. Environment variables solve this by defining values once at the top of your pipeline and referencing them everywhere. You'll also set up automatic polling so Jenkins detects new commits without you clicking Build Now every time.

In this step, get ready to:
  • Add environment variables to your Jenkinsfile.
  • Trigger a new build and verify variables appear in Console Output.
  • Configure Poll SCM to automatically detect code changes.
Add environment variables to your Jenkinsfile

An environment block lets you define key-value pairs that every stage in your pipeline can access. Instead of repeating "my-app" and "1.0.0" in three different places, you define them once and reference them with ${env.VARIABLE_NAME} syntax.

  • Open the Jenkinsfile in your code editor (inside your cloned jenkins-pipeline-demo folder).
  • Select all the existing content and replace it with this updated pipeline:
pipeline {
    agent any
    environment {
        APP_NAME = 'my-app'
        APP_VERSION = '1.0.0'
    }
    stages {
        stage('Build') {
            steps {
                echo "Building ${env.APP_NAME} version ${env.APP_VERSION}..."
                sh 'echo "Compiling source code..."'
            }
        }
        stage('Test') {
            steps {
                echo "Running tests for ${env.APP_NAME}..."
                sh 'echo "Running unit tests..."'
                sh 'echo "Running integration tests..."'
                sh 'echo "All tests passed!"'
            }
        }
        stage('Deploy') {
            steps {
                echo "Deploying ${env.APP_NAME} v${env.APP_VERSION} to production..."
                sh 'echo "Application deployed successfully!"'
            }
        }
    }
    post {
        always {
            echo "Pipeline for ${env.APP_NAME} finished."
        }
        success {
            echo 'SUCCESS: All stages completed!'
        }
        failure {
            echo 'FAILURE: Check logs for errors.'
        }
    }
}

What changed in this pipeline?

The environment block near the top defines two variables: APP_NAME and APP_VERSION. Every stage now references these with ${env.APP_NAME} instead of hardcoded strings.

The post block also gained an always condition. This runs whether the pipeline succeeds or fails. It prints a summary message regardless of outcome.

Notice the Test stage now has separate sh commands for unit and integration tests. This reflects how real pipelines break testing into distinct phases.

  • Save Jenkinsfile.

Why sh and not bat?

Your local machine runs Windows, but the Jenkinsfile uses sh for shell commands. That's because the pipeline executes inside the Jenkins Docker container, which is a Linux environment.

The bat step is only for pipelines running on native Windows agents. Since your Jenkins is a Linux container, sh is the correct step.

Seeing a syntax error when you save?

Make sure double-quoted strings use " (straight quotes) and single-quoted strings use '. Curly/smart quotes from word processors break Groovy syntax.

Also check that the environment block sits directly inside pipeline { }, at the same level as stages and post.

help me fix a syntax error in my Jenkinsfile environment block

Commit, push, and trigger a new build

Your updated Jenkinsfile is saved locally but Jenkins doesn't know about it yet. You need to push it to GitHub so Jenkins can pull the latest version.

  • Commit and push the updated Jenkinsfile by running these commands in your terminal (from inside your jenkins-pipeline-demo folder):
git add Jenkinsfile
git commit -m "Add environment variables to pipeline"
git push origin main

What do these commands do?

git add Jenkinsfile stages the file for commit. git commit saves a snapshot with a descriptive message. git push origin main sends that snapshot to your GitHub repository on the main branch.

  • Switch back to Jenkins at http://localhost:8080.
  • Click my-first-pipeline from the dashboard to open your pipeline project.
  • Click Build Now in the left sidebar.
  • Click on the new build number (#2) that appears in the Build History panel.
  • Click Console Output in the left sidebar.

You should see your environment variables interpolated in the output. Look for lines like Building my-app version 1.0.0... and Deploying my-app v1.0.0 to production... instead of the generic strings from build #1.

Still seeing the old output?

If the Console Output still shows the old messages (like "Building the application..."), Jenkins may have cached the old Jenkinsfile. Confirm your push succeeded by checking your repository on GitHub. The Jenkinsfile there should show the environment block.

If the push succeeded but Jenkins shows old output, click Build Now once more. Jenkins fetches fresh code from your repository each time it builds.

help me troubleshoot why Jenkins is not picking up my new Jenkinsfile changes

Configure Poll SCM to check for changes automatically

Clicking Build Now every time you push is tedious. Poll SCM tells Jenkins to check your repository on a schedule and automatically start a build if it finds new commits.

  • Return to your pipeline's main page (click my-first-pipeline in the breadcrumb at the top).
  • Click Configure in the left sidebar.
  • Scroll down to the Build Triggers section.
  • Check the Poll SCM checkbox.
  • In the Schedule field that appears, enter this cron expression:
H/5 * * * *

What does this schedule mean?

H/5 * * * * is a cron-style schedule that tells Jenkins to check your GitHub repository for new commits every 5 minutes. The H spreads load by letting Jenkins pick the exact minute within each 5-minute window.

If Jenkins finds new commits since the last build, it automatically triggers a pipeline run. No more manual clicking.

  • Click Save at the bottom of the configuration page.

You should be back on your pipeline's main page. From now on, Jenkins checks your repository every 5 minutes and builds automatically when it detects changes.

Why Poll SCM instead of webhooks?

Webhooks are the industry standard for production Jenkins servers. They notify Jenkins instantly when a push happens. However, webhooks require a publicly accessible URL.

Since your Jenkins runs on localhost, GitHub can't reach it. Poll SCM is the right choice for a local learning environment.

Don't see the Poll SCM option?

Make sure you're in the pipeline's Configure page, not the general Jenkins system settings. The Build Triggers section appears below General and above Pipeline on the configuration page.

help me find the Poll SCM setting in my Jenkins pipeline configuration

✔️ Awesome, I've got everything!

Great. Double check you've saved your Jenkinsfile and the Jenkins configuration.

ⓧ I'd like to double check the full code

Here's the complete Jenkinsfile you should have at this point:

pipeline {
    agent any
    environment {
        APP_NAME = 'my-app'
        APP_VERSION = '1.0.0'
    }
    stages {
        stage('Build') {
            steps {
                echo "Building ${env.APP_NAME} version ${env.APP_VERSION}..."
                sh 'echo "Compiling source code..."'
            }
        }
        stage('Test') {
            steps {
                echo "Running tests for ${env.APP_NAME}..."
                sh 'echo "Running unit tests..."'
                sh 'echo "Running integration tests..."'
                sh 'echo "All tests passed!"'
            }
        }
        stage('Deploy') {
            steps {
                echo "Deploying ${env.APP_NAME} v${env.APP_VERSION} to production..."
                sh 'echo "Application deployed successfully!"'
            }
        }
    }
    post {
        always {
            echo "Pipeline for ${env.APP_NAME} finished."
        }
        success {
            echo 'SUCCESS: All stages completed!'
        }
        failure {
            echo 'FAILURE: Check logs for errors.'
        }
    }
}

Secret mission

Add a Manual Approval Gate

In real-world deployments, teams don't push straight to production without a human checkpoint. Add a staging environment with a manual approval step that pauses your pipeline and waits for you to say 'go' before deploying to production.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

This project runs entirely locally inside Docker, so there are no ongoing cloud costs.

Resources you used:

  • Docker container named jenkins running on port 8080.
  • Docker volume named jenkins-data storing all Jenkins configuration.
  • Docker network named jenkins.

Keep everything running

No action needed. Choose this if you're still actively building or want to keep experimenting with your Jenkins pipeline.

  • Leave Docker Desktop running. Jenkins will restart automatically with Docker.
  • Access Jenkins anytime at http://localhost:8080.
  • Your pipeline configuration and build history persist in the jenkins-data volume.

Pause - I'll come back to this later

Shut down the Jenkins container to free up memory. Your data persists in the volume so you can pick up where you left off.

  • Stop the Jenkins container by running:
docker stop jenkins
  • When you're ready to come back, restart it by running:
docker start jenkins

Your pipeline configuration, build history, and plugins all persist in the jenkins-data volume.

Delete - I don't want to use this again

Remove all Docker resources created during this project. This cannot be undone.

  • Stop and remove the Jenkins container by running:
docker stop jenkins
docker rm jenkins
  • Remove the Jenkins data volume by running:
docker volume rm jenkins-data
  • Remove the Docker network by running:
docker network rm jenkins

After running these commands, all Jenkins data, plugins, and build history are permanently deleted.

That's a Wrap!

That's a Wrap!

Nice work! You just built a fully functional CI/CD pipeline from scratch using Jenkins and Docker. You now understand how professional engineering teams automate their software delivery process.

You've learned how to:

  • Launch a Jenkins server inside a Docker container, skipping manual Java installation entirely.
  • Create a Declarative Pipeline with Build, Test, and Deploy stages that runs automatically from a Jenkinsfile stored in GitHub.
  • Configure environment variables, Poll SCM triggers, and post-build conditions to parameterize and automate your pipeline.
  • Add a manual approval gate between staging and production deployment stages.

Ready to quiz yourself?