Automating CI/CD for MyNotes: A Seamless Deployment Pipeline

Omkar MahanduleOmkar Mahandule
3 min read

Introduction

Continuous Integration and Continuous Deployment (CI/CD) is a game-changer in modern software development. It streamlines code integration, testing, and deployment, ensuring rapid and reliable delivery of applications. In this blog, I’ll share my experience setting up a CI/CD pipeline for MyNotes, a simple application, using Jenkins, GitHub, Docker, and Webhooks.

Why Automate Deployment?

Manually building, testing, and deploying applications can be time-consuming and prone to errors. Automating these steps with a CI/CD pipeline offers:

  • Faster delivery cycles

  • Minimized manual intervention

  • Consistent and reliable deployments

  • Immediate feedback on code changes

CI/CD Pipeline Overview

The goal is to automate the Build, Test, and Deploy stages every time code is pushed to the GitHub repository. Here’s how the process works:

Setting Up the CI/CD Pipeline

1️⃣ Installing and Configuring Jenkins

Jenkins is the automation server at the heart of this pipeline. I installed Jenkins on my local machine using:

sudo apt update
sudo apt install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
echo "deb http://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update
sudo apt install jenkins

After starting Jenkins, I installed the required plugins: GitHub, Docker Pipeline, and Credentials Binding.

2️⃣ Configuring GitHub Webhook

To automatically trigger Jenkins on a code push, I:

  • Generated a Personal Access Token with repo and admin:repo_hook permissions.

  • Configured a Webhook in my GitHub repository with the URL: http://my-jenkins-server/github-webhook/.

3️⃣ Writing the Jenkinsfile

The Jenkins pipeline script (Jenkinsfile) defines the Build, Push to DockerHub, and Deploy stages:

pipeline {
    agent { label "agent1" }
    stages {
        stage('Build') {
            steps {
                echo "Cloning repository..."
                git url: "https://github.com/o/mynotes.git", branch: "main"  # Cloning the Repo 
                echo "Building Docker image..."
                sh "docker build -t mynotes:latest ."    # Building Docker image
            }
        }
        stage('Push to DockerHub') {
            steps {
                echo "Pushing image to DockerHub..."
                withCredentials([usernamePassword(credentialsId: 'dockerHubCred', 
                usernameVariable: 'dockerHubUser', passwordVariable: 'dockerHubPass')]) {  # Adding Username & Pass with essential security measures.
                    sh "echo \"$dockerHubPass\" | docker login -u \"$dockerHubUser\" --password-stdin"
                    sh "docker tag mynotes:latest $dockerHubUser/mynotes:latest"
                    sh "docker push $dockerHubUser/mynotes:latest" # Push on DockerHub
                }
            }
        }
        stage('Deploy') {
            steps {
                echo "Deploying application..."
                sh "docker-compose up -d"   # Deploy the appication.
            }
        }
    }
}

4️⃣ Running the Pipeline

Once the Jenkins pipeline was set up, I tested it by committing changes to GitHub. The webhook successfully triggered Jenkins, and the pipeline executed all stages seamlessly.

Pipeline Execution Outputs

Below are some outputs observed during pipeline execution:

1. Build Stage Output:

Cloning repository...
Building Docker image...
Successfully built 3a7e72f1c9c3
Successfully tagged mynotes:latest

2. Push to DockerHub Stage Output:

Pushing image to DockerHub...
Login Succeeded
The push refers to repository [docker.io/yourusername/mynotes]
latest: Pushed

3. Deploy Stage Output:

Deploying application...
Creating network "mynotes_default" with the default driver
Creating mynotes_app_1 ... done

Console output:

Troubleshooting Issues

During the setup, I encountered and resolved the following issues:

  • GitHub Webhook Not Triggering → Fixed by using ngrok to expose Jenkins publicly.

  • Jenkins Agent Going Offline → Ensured proper file permissions and stable connectivity.

  • DockerHub Authentication Failed → Resolved by enabling 2FA and using a Docker Access Token.

Conclusion

With this automated CI/CD pipeline, MyNotes is now continuously integrated and deployed with minimal effort. This setup ensures that each code change is instantly built, tested, and deployed, keeping the application reliable and up-to-date.

10
Subscribe to my newsletter

Read articles from Omkar Mahandule directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Omkar Mahandule
Omkar Mahandule

I am an aspiring DevOps & Cloud Engineer with a strong drive to learn, grow, and contribute to the world of automation, cloud computing, and scalable infrastructure. Passionate about automation, cloud computing, and scalable infrastructure. With a strong foundation in Linux, Git/GitHub, CI/CD, Docker, Kubernetes, and AWS, I have already completed the core phases of my DevOps journey and am now advancing into Infrastructure as Code (Terraform, Ansible), Monitoring, and DevSecOps. 💻 What I Bring to the Table: 🐧 Linux & Scripting – Shell scripting, process management, automation. 🌱 Version Control – Git, GitHub/GitHub Actions, branching strategies. ⚡ CI/CD Pipelines – Jenkins, GitHub Actions, CI/CD. 🐳 Containers & Orchestration – Docker, Kubernetes (Minikube, EKS). ☁️ Cloud Computing – AWS (EC2, S3, IAM, RDS, VPC, Load Balancers). 🎯 Next Steps in My DevOps Journey: 🏗️ Mastering Infrastructure as Code (Terraform, Ansible) for automated provisioning. 📊 Learning Monitoring & Observability (Prometheus, Grafana, AWS CloudWatch, ELK Stack). 🔒 Exploring DevSecOps by implementing security scanning and best practices in CI/CD. 🛡️ Deepening my expertise in Kubernetes security (RBAC, Network Policies).