Building a CI/CD Pipeline for a Django-Based Web Application Using Jenkins

Building a CI/CD Pipeline for a Django-Based Web Application Using Jenkins

Introduction

In today's fast-paced world, software development demands efficient, automated, and reliable processes. A CI/CD (Continuous Integration/Continuous Deployment) pipeline is a key component of modern software development, enabling teams to deliver high-quality applications quickly and consistently. In this article, we'll walk you through the process of setting up a CI/CD pipeline for a Django-based web application using Jenkins, a popular automation server. Our project, the "Django To-Do List App," is hosted on GitHub and will be containerized using Docker for deployment.

Scenario

Imagine you are the lead developer of the "Django To-Do List App." Your team is working on a new feature, and you need to automate the deployment process to ensure that new changes are tested and deployed seamlessly. To achieve this, you decide to implement a CI/CD pipeline with Jenkins. This pipeline will continuously build, and deploy your application whenever there are changes pushed to your GitHub repository.

Objectives

  • Dockerize the Django-based To-Do List App.

  • Set up a Jenkins server on an Ubuntu machine.

  • Create a Jenkins job and build a CI/CD pipeline that includes steps for GitHub integration, Docker containerization, and deployment to an Ubuntu server.

  • Implement a declarative pipeline.

  • Configure a GitHub webhook to trigger the pipeline on code changes.

1. Dockerize the Application

First, ensure your Django To-Do List App is containerized using Docker. This allows for consistent and portable deployments. Create a Dockerfile to define the container image.

sudo apt-get update -y
sudo apt-get install docker.io
sudo usermod -aG docker $USER
sudo apt-get install docker-compose
docker login

After this, you need to give a username and password for the DockerHub account

Dockerfile

# Use Python 3.9 as the base image
FROM python:3.9

# Set the working directory within the container
WORKDIR /app/backend

# Copy the requirements.txt file to the container
COPY requirements.txt /app/backend

# Install Python dependencies using pip
RUN pip install -r requirements.txt

# Copy the entire application code to the container
COPY . /app/backend

# Expose port 8000 to the outside world
EXPOSE 8000

# Apply migrations to set up the database (SQLite in this case)
RUN python manage.py migrate

# Run the Django application
CMD python /app/backend/manage.py runserver 0.0.0.0:8000

2. Deploy Application on Ubuntu Server

Set up an Ubuntu server where your Dockerized app will run. You can use cloud providers like AWS, Azure, or your own infrastructure.

Clone the repository

git clone git@github.com:siddhantbhattarai/Django-Todo-App.git

Build the app

docker build -t todo-list-app .

Run the app

docker run -d -p 8000:8000 todo-list-app:latest

3. Clone the GitHub Repository

Clone your project's GitHub repository onto the Ubuntu server where your application will be deployed.

git clone git@github.com:siddhantbhattarai/Django-Todo-App.git

4. Build a Docker Container

Using the Dockerfile, build a Docker container for your Django app on the Ubuntu server.

docker build -t todo-list-app .

5. Local Testing

Verify that your Docker container runs correctly on the Ubuntu server, ensuring that your Django application is functioning as expected.

6. Install Jenkins on Ubuntu Server

Install Jenkins on your Ubuntu server by following the steps outlined in the Jenkins documentation.

sudo apt update
sudo apt install fontconfig openjdk-17-jre
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian/jenkins.io-2023.key
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debianbinary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins
sudo usermod -aG docker jenkins

7. Create Your First Jenkins Job

Configure Jenkins by creating a new job. Use Jenkins' "Pipeline" plugin to define your CI/CD pipeline. Your pipeline should include stages for GitHub integration, building a Docker image, pushing the image to Docker Hub, and deploying to the Ubuntu server.

  • Log in to Jenkins: Open your Jenkins web interface and log in using your credentials.

  • Create a New Item:

  • Click on "New Item" on the Jenkins dashboard.

  • Enter a name for your job/pipeline and select the type (e.g., "Pipeline").

  • Configure General Settings:

  • Define a description (optional) to describe the purpose of your job/pipeline.

  • Choose the "Discard old builds" option to manage build history.

  • Set build triggers, such as "Build after other projects are built" or "Build periodically" (if needed).

Jenkinsfile

pipeline {
    agent any

    stages {
        stage("Clone Code") {
            steps {
                echo "Cloning the code"
                git url: "https://github.com/siddhantbhattarai/Django-Todo-App.git", branch: "main"
            }
        }

        stage("Build") {
            steps {
                echo "Building the Docker image"
                sh "docker build -t todo-list-app ."
            }
        }

        stage("Push to Docker Hub") {
            steps {
                echo "Pushing the Docker image to Docker Hub"
                withCredentials([usernamePassword(credentialsId: "dockerHub", passwordVariable: "dockerHubPass", usernameVariable: "dockerHubUser")]) {
                    sh "docker tag todo-list-app ${env.dockerHubUser}/todo-list-app:latest"
                    sh "docker login -u ${env.dockerHubUser} -p ${env.dockerHubPass}"
                    sh "docker push ${env.dockerHubUser}/todo-list-app:latest"
                }
            }
        }

        stage("Deploy") {
            steps {
                echo "Deploying the container"
                sh "docker-compose down && docker-compose up -d"
            }
        }
    }
}

8. Set Up a Declarative Pipeline

Utilize Jenkins' declarative pipeline syntax to define your pipeline in code. This makes your pipeline more maintainable and version-controlled.

9. Set Up a GitHub Webhook

Configure a webhook in your GitHub repository settings that triggers your Jenkins pipeline whenever code is pushed. This ensures that your pipeline is automatically initiated with each code change.

10. Testing the CI/CD Pipeline

Test the complete CI/CD pipeline by making changes to your Django app and pushing them to the GitHub repository. Jenkins should automatically build and deploy our application to the Ubuntu server.

Here, our to-do-list app is successfully pushed to DockerHub.

Conclusion

By setting up a CI/CD pipeline for your Django-based To-Do List App using Jenkins, you've automated the process of building, testing, and deploying your application. This ensures that your software development workflow is streamlined, efficient, and reliable. With automated testing and deployment, you can confidently release new features and improvements to your users with minimal manual intervention, reducing the risk of errors and improving your development team's productivity.