Setting Up a CI/CD Pipeline for Your React Application with Jenkins ,Docker and Gitlab

·

5 min read

In today's software development landscape, continuous integration and continuous deployment (CI/CD) pipelines have become indispensable tools for streamlining the development and deployment processes. In this blog post, I guide you through the steps to configure a CI/CD pipeline for a React application using Jenkins and GitLab.

Introduction

Jenkins and GitLab are powerful tools that, when combined, provide an efficient and automated way to build, test, and deploy your React applications. This setup allows you to automate repetitive tasks and ensure that your code is always deployable. Let's dive into the steps required to set up this CI/CD pipeline.

Step 1: Configuring Jenkins Plugins

Before we get started, we need to make sure that Jenkins is equipped with the necessary plugins. We'll use the following plugins:

1. CloudBees Docker Build and Publish

This plugin is essential for building and publishing Docker images to a registry. You can find it here.

2. Git Plugin

The Git plugin enables Jenkins to pull code bases from your Git repositories. You can find it here.

3. SSH Agent Plugin

The SSH Agent plugin allows you to provide SSH credentials to builds via a SSH agent in Jenkins. You can find it here.

4. Node.js Plugin

To build Node.js applications, you'll need to install and configure the Node.js plugin. This plugin allows you to specify the required Node.js version. You can find it here.

5. GitLab Plugin

The GitLab plugin enables GitLab to trigger builds in Jenkins when code is committed or merge requests are opened/updated. It can also send build status back to GitLab. You can find it here.

Step 2: Generating a GitLab Access Token

To link GitLab with Jenkins, you'll need to generate a GitLab access token. Follow these steps:

  1. Go to your GitLab profile section.

  2. Click on "Preferences," then select "Access Tokens."

  3. Add a new token, providing a name and setting an expiration date.

  4. Select the required scopes for the token.

  5. Create the personal access token.

Step 3: Adding GitLab Access Token to Jenkins

Now, let's add the GitLab access token to Jenkins:

  1. In Jenkins, navigate to "Manage Jenkins" > "Credentials" > "System" > "Global credentials (unrestricted)."

  2. Click on "Add credentials."

  3. Select "Gitlab API token" as the kind.

  4. Paste your GitLab API token.

  5. Enter an ID and description for the credentials.

  6. Save your credentials.

Step 4: Configure Jenkins with Your GitLab Project

To establish the connection between Jenkins and your GitLab project, follow these steps:

  1. In Jenkins, go to "Manage Jenkins" > "Configure System."

  2. In the GitLab section, enter the GitLab host URL and a connection name.

  3. Test the configuration.

  4. Apply the settings and save your changes.

Step 5: Adding a Webhook to GitLab

Webhooks play a crucial role in automating the CI/CD process. Follow these steps to add a webhook to GitLab:

  1. In Jenkins pipeline configuration, under "Build triggers," check "Build when a change is pushed to GitLab."

  2. Copy the GitLab webhook URL.

  3. Click on "Advanced" and generate a secret token.

  4. In GitLab, navigate to your project's settings, then go to "Webhooks."

  5. Enter the copied webhook URL.

  6. Copy the generated secret token from GitLab and enter it in Jenkins.

  7. Under triggers, check all items and add the webhook.

  8. In GitLab, go to "Integration" > "Jenkins" and enter the Jenkins server URL, project name, Jenkins username, and password.

  9. Test the settings and save.

Below is Jenkins pipeline script designed to build and deploy a React application

pipeline {

    agent any

    tools { nodejs "node18" }

    environment {
        // Define environment variables used throughout the pipeline
        registryUrl = "http://YOUR_REGISTRY_IP:PORT"  // Replace with your Docker registry URL
        imageTag = "YOUR_REGISTRY_IP:PORT/reactapp"   // Replace with your Docker image tag
        dockerImage = ''
        serverIp = "YOUR_SERVER_IP"                    // Replace with your server's IP address
        serverUser = "YOUR_SERVER_USERNAME"            // Replace with your server's username
    }

    stages {

        stage('Checkout') {
            steps {
                // Checkout the code from your Git repository
                git 'https://github.com/mwaijohn/reactjenkins.git'
            }
        }

        stage('Build React App') {
            steps {
                // Install project dependencies and build the React application
                sh 'npm install'
                sh 'npm run build'
            }
        }

        stage('Build and Run Docker Container') {
            steps {
                script {
                    // Build a Docker image using the provided imageTag and the current BUILD_ID
                    img = imageTag + ":${env.BUILD_ID}"
                    println ("${img}")
                    dockerImage = docker.build("${img}")
                }
            }
        }

        stage('Push To Registry') {
            steps {
                script {
                    // Push the Docker image to the Docker registry
                    docker.withRegistry("${registryUrl}") {
                        dockerImage.push()
                    }
                }
            }
        }

        stage('Deploy to Server Server') {
            steps {
                script {
                    // Define Docker container management and deployment commands
                    def stopcontainer = "docker stop ${JOB_NAME}"
                    def delcontName = "docker rm ${JOB_NAME}"
                    def delimages = 'docker image prune -a --force'
                    def drun = "docker run -d --name ${JOB_NAME}-${BUILD_NUMBER} -p 3000:3000 ${img}"
                    println "${drun}"

                    // SSH into the server and execute Docker container management and deployment commands
                    sshagent(['kubernetes-master']) {
                        sh returnStatus: true, script: "ssh -o StrictHostKeyChecking=no ${serverUser}@${serverIp} ${stopcontainer} "
                        sh returnStatus: true, script: "ssh -o StrictHostKeyChecking=no ${serverUser}@${serverIp} ${delcontName}"
                        sh returnStatus: true, script: "ssh -o StrictHostKeyChecking=no ${serverUser}@${serverIp} ${delimages}"

                        // Start a Docker container on the server
                        sh "ssh -o StrictHostKeyChecking=no ${serverUser}@${serverIp} ${drun}"
                    }
                }
            }
        }
    }
}

Explanation of the script:

  1. Agent: The pipeline runs on any available agent.

  2. Tools: The Node.js tool with the label "node18" is used in this pipeline.

  3. Environment: Environment variables are defined for the Docker registry URL, Docker image tag, Docker image name, server IP address, and server username.

  4. Stages: The pipeline consists of several stages.

    • Checkout: This stage checks out the code from your Git repository.

    • Build React App: It installs project dependencies and builds the React application.

    • Build and Run Docker Container: This stage builds a Docker image using the provided image tag and current build ID.

    • Push To Registry: The Docker image is pushed to the specified Docker registry.

    • Deploy to Server Server: This stage defines commands for managing Docker containers on the server, such as stopping and removing containers. It also deploys a new Docker container on the server with port mapping.

Please replace the placeholders (YOUR_REGISTRY_IP, YOUR_SERVER_IP, YOUR_SERVER_USERNAME) with your actual values. This script automates the deployment of your React application, making it a crucial part of your CI/CD pipeline.