<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adetokun Halimat</title>
    <description>The latest articles on DEV Community by Adetokun Halimat (@adetokunadenike).</description>
    <link>https://dev.to/adetokunadenike</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2417875%2F12533e50-8831-4abf-bd0d-95350785988d.jpeg</url>
      <title>DEV Community: Adetokun Halimat</title>
      <link>https://dev.to/adetokunadenike</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adetokunadenike"/>
    <language>en</language>
    <item>
      <title>Building a CI/CD Pipeline for a Flask API Using Jenkins and Docker</title>
      <dc:creator>Adetokun Halimat</dc:creator>
      <pubDate>Fri, 24 Jan 2025 12:24:10 +0000</pubDate>
      <link>https://dev.to/adetokunadenike/building-a-cicd-pipeline-for-a-flask-api-using-jenkins-and-docker-5f6o</link>
      <guid>https://dev.to/adetokunadenike/building-a-cicd-pipeline-for-a-flask-api-using-jenkins-and-docker-5f6o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facfm89fufqzkvoivndas.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facfm89fufqzkvoivndas.jpg" alt="CI/CD Architecture" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Continuous Integration and Continuous Deployment (CI/CD) is a crucial part of modern software development. In this article, I will walk you through how I built a CI/CD pipeline for a Flask-based Random Quote API using Jenkins and Docker. This project automates the process of testing and deploying the API, ensuring that any updates to the repository are immediately built, tested, and deployed without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;The Random Quote API is a simple RESTful API that returns quotes. It includes endpoints to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fetch all quotes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fetch a random quote&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fetch a specific quote by ID&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire project follows DevOps best practices by implementing CI/CD automation.&lt;/p&gt;

&lt;p&gt;Tech Stack&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Flask: Web framework for Python&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker: Containerization tool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jenkins: CI/CD automation server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub: Version control&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the CI/CD Pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Setting Up the GitHub Repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step is to host the project on GitHub. The repository contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;app.py&lt;/code&gt;: The main Flask application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;: Instructions to containerize the application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Jenkinsfile&lt;/code&gt;: The pipeline configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;requirements.txt&lt;/code&gt;: Dependencies for the application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tests/&lt;/code&gt;: Unit tests for the API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Writing the Jenkinsfile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jenkinsfile is a script that defines the automation process in Jenkins. Below is the Jenkinsfile used for this project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipeline {
    agent any

    stages {
        stage('Checkout Code') {
            steps {
                git branch: 'main', url: 'https://github.com/your-username/random-quote-api.git'
            }
        }

        stage('Build Docker Image') {
            steps {
                sh 'DOCKER_BUILDKIT=1 docker build -t random-quote-api .'
            }
        }

        stage('Run Unit Tests') {
            steps {
                sh 'docker run --rm random-quote-api pytest'
            }
        }

        stage('Deploy Application') {
            steps {
                sh 'docker run -d -p 5000:5000 random-quote-api'
            }
        }
    }

    post {
        success {
            echo 'Pipeline executed successfully!'
        }
        failure {
            echo 'Pipeline failed. Check logs for details.'
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Installing and Configuring Jenkins&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To install Jenkins, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install jenkins -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to start Jenkins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service jenkins start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, access Jenkins in the browser using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Setting Up the Jenkins Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new Pipeline project in Jenkins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link the repository to Jenkins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure Jenkins has Git and Docker installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add necessary credentials (GitHub, Docker permissions).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Running the CI/CD Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every time code is pushed to the repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Jenkins pulls the latest changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker builds a new container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests are executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If tests pass, the application is deployed automatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demonstrating the API
&lt;/h2&gt;

&lt;p&gt;To test the API after deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check running containers:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Fetch all quotes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://127.0.0.1:5000/api/quotes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Fetch a random quote:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://127.0.0.1:5000/api/quotes/random
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Fetch a specific quote by ID:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://127.0.0.1:5000/api/quotes/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges and Learnings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Challenges:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setting up Jenkins on WSL required extra configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jenkins initially lacked access to Docker, requiring user permission fixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Troubleshooting firewall and port issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Learnings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automating deployment saves time and reduces errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CI/CD ensures code quality by running tests before deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker makes application deployment more scalable and portable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project highlights how Jenkins and Docker can be leveraged to automate the testing and deployment of a Python Flask API. Setting up a CI/CD pipeline ensures seamless integration of code updates, leading to a more efficient and reliable development workflow.&lt;/p&gt;

&lt;p&gt;By following these steps, you can integrate CI/CD into your projects and ensure a smoother, more automated development process.&lt;/p&gt;

&lt;p&gt;Future Plans?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deploy the API to a cloud provider (AWS, GCP, or Heroku).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement database integration to store and manage quotes, as the current implementation temporarily uses JSON for storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend CI/CD to include automated security checks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to hear your thoughts! Let me know if you have implemented CI/CD in your projects and the challenges you faced.&lt;/p&gt;

&lt;p&gt;Here is a link to the repository on &lt;a href="https://github.com/AdetokunAdenike/random-quote-api" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
