← Back to Home
πŸ‘·

A Full CI/CD Pipeline

Build, containerise, push, and deploy β€” with a human gate before production.

⏱11 min readπŸ“šDevOps Fundamentals

Time to connect everything you’ve learned into one real pipeline. We’ll take code, test it, package it as a Docker image, push it to a registry, and deploy it β€” with an approval step before production. This is a genuine end-to-end CI/CD flow.


🎯 Learning Objectives

By the end of this lesson you will:


The Pipeline Stages

A production CI/CD pipeline usually flows like this:

text
Checkout β†’ Test β†’ Build Image β†’ Push Image β†’ Deploy Staging β†’ [Approve] β†’ Deploy Prod

Each stage builds on the last, and the approval gate ensures a human confirms before the highest-risk step.


Building and Pushing a Docker Image

Using an image tagged with the build number gives every build a unique, traceable artifact:

groovy
stage('Build Image') {
steps {
  sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
stage('Push Image') {
steps {
  withCredentials([usernamePassword(
    credentialsId: 'dockerhub',
    usernameVariable: 'USER',
    passwordVariable: 'PASS')]) {
    sh '''
      echo "$PASS" | docker login -u "$USER" --password-stdin
      docker push myapp:${BUILD_NUMBER}
    '''
  }
}
}

πŸ’‘ Tag with the build number

myapp:${BUILD_NUMBER} gives each build a unique tag, so you always know exactly which image is running and can roll back to a specific one. Avoid deploying latest to production β€” it’s ambiguous.


The Approval Gate

The input step pauses the pipeline and waits for a human to approve β€” perfect before a production deploy:

groovy
stage('Approve Production') {
steps {
  input message: 'Deploy to production?', ok: 'Deploy'
}
}
stage('Deploy Production') {
steps {
  sh './deploy.sh production myapp:${BUILD_NUMBER}'
}
}
bash β€” 80Γ—24
student@devops:~$# Stage View, paused at the gate:

⚠ Guard the input step

By default anyone with access can approve an input. Use the submitter parameter to restrict approval to specific users or groups, so only authorised people can release to production.


Putting It All Together

The complete Jenkinsfile:

groovy
pipeline {
agent any
environment { IMAGE = "myapp:${BUILD_NUMBER}" }

stages {
  stage('Checkout') { steps { checkout scm } }
  stage('Test')     { steps { sh 'npm ci && npm test' } }
  stage('Build Image') { steps { sh 'docker build -t $IMAGE .' } }
  stage('Push Image') {
    steps {
      withCredentials([usernamePassword(credentialsId: 'dockerhub',
        usernameVariable: 'USER', passwordVariable: 'PASS')]) {
        sh 'echo "$PASS" | docker login -u "$USER" --password-stdin && docker push $IMAGE'
      }
    }
  }
  stage('Deploy Staging') { steps { sh './deploy.sh staging $IMAGE' } }
  stage('Approve') { steps { input message: 'Deploy to production?', ok: 'Deploy' } }
  stage('Deploy Production') { steps { sh './deploy.sh production $IMAGE' } }
}

post {
  failure { echo 'Build failed β€” notify the team' }
  always  { sh 'docker logout || true' }
}
}

πŸ§ͺ Hands-on Lab

πŸ“

Design a CI/CD Pipeline

  1. Sketch a Jenkinsfile that tests, builds a Docker image tagged with the build number, and pushes it
  2. Add a staging deploy, an approval gate, then a production deploy
  3. Add a post failure notification and a docker logout in always

🧠 Knowledge Check

Knowledge Check

Why tag a Docker image with the build number instead of just 'latest' in a CI/CD pipeline?

Knowledge Check

What does the input step do in a Jenkins pipeline?


πŸ’Ό Interview Preparation

Interview Q&A

Describe a complete CI/CD pipeline you've designed or would design in Jenkins.


Summary

You’ve completed the Jenkins track: architecture, setup and jobs, pipelines as code, and now a full CI/CD pipeline with Docker, registry push, and an approval gate. You can automate delivery end to end. Next, we step into the frontier: Agentic AI for DevOps.

Up Next

Introduction to Agentic AI

You've mastered this lesson. Continue your journey to becoming a DevOps Engineer.

Start Next Lesson→