In this article, we are going to learn how deploy a NodeJS application to Kubernetes using GitOps way by using Jenkins & ArgoCD. We will use Jenkins to checkout the code from repo, build the Docker image, push it to Docker Hub & to update Kustomize manifest in different repo. Then we will use ArgoCD to deploy the application to Kubernetes. In this project we will use two repositories. One for the application code & the other for the Kustomize manifest. Let's start.

Prerequisites

  • A GitHub repository containing your NodeJS Project
  • A Docker Hub account
  • A Kubernetes cluster with ArgoCD installed
  • A GitHub repository for Kustomize manifest
  • A Jenkins server
  • Create Jenkins file

    First we need to create a Jenkins file with instructions which need to build the docker image & push it to Docker Hub. Create a file named Jenkinsfile in the root of your project. Now add the following code to the file.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    pipeline {

    agent any // run on any agent

    stages {

    stage('Checkout Code') {
    echo 'Checking out code'
    }

    stage('Build Docker Image') {
    echo 'Building Docker Image'
    }

    stage('Tag Docker Image') {
    echo 'Tagging Docker Image'
    }

    stage('Push Docker Image to Docker Hub') {
    echo 'Pushing Docker Image to Docker Hub'
    }

    stage('Remove Docker Image') {
    echo 'Removing Docker Image'
    }

    stage('Update Manifest') {
    echo 'Updating Manifest'
    }

    }

    post {
    always {
    cleanWs() // clean workspace
    }
    }

    }

    Let’s now move to our steps.

    Checkout Code

    First we need to checkout the code from the repository. For that we need to add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    stage('Checkout') {
    steps {
    git branch: 'main', url: 'https://github.com/yourusername/your-repo.git'
    }
    }

    This will checkout the code from the repository. You can change the branch name & the URL according to your repository. If you are using a private repository, you need to configure Jenkins with the necessary credentials to access the repository.

    Build Docker Image

    Now we need to to build the Docker image. To build docker image, I am using the Dockerfile in the root of the project. You can change the path according to your project. Add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    stage('Build Docker Image') {
    steps {
    sh "docker build --no-cache . -t <your-image-name>:v${BUILD_NUMBER}"
    }
    }

    This command will the build Docker iamge & tag it with the build number of the Jenkins job. In here I am using the –no-cache flag not to use cached layers during the build, ensuring a clean build each time. This is useful when you want to make sure that the build uses the latest versions of all dependencies. You can remove this flag if you don’t want to use it.

    Tag Docker Image

    In this step we need to tag the Docker image with the Docker Hub repository name. Add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    stage('Tag Docker Image') {
    steps {
    sh "docker tag <your-image-name>:v${BUILD_NUMBER} <your-dockerhub-repository>/<your-image-name>:v${BUILD_NUMBER}"
    }
    }

    Push Docker Image to Docker Hub

    Now it's time to push the Docker image to Docker Hub. Add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    6
    7
    stage('Push Docker Image to Docker Hub') {
    steps {
    withDockerRegistry([ credentialsId: 'DockerHubCredentials', url: '' ]) {
    sh "docker push <your-dockerhub-repository>/<your-image-name>:v${BUILD_NUMBER}"
    }
    }
    }

    In here we are using the withDockerRegistry step to login to Docker Hub. You need to configure Jenkins with the necessary credentials to access the Docker Hub.

    Remove Docker Image

    Now we need to remove the Docker image from the Jenkins server. Add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    6
    stage('Remove Docker Image') {
    steps{
    sh "docker rmi <your-image-name>:v${BUILD_NUMBER}"
    sh "docker rmi <your-dockerhub-repository>/<your-image-name>:v${BUILD_NUMBER}"
    }
    }

    Update Manifest

    Now we need to update the Kustomize manifest in the other repository. For that we need to clone the repository & update the manifest. Add the following code to the Jenkins file.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    stage('Update Manifest') {
    steps {
    withCredentials([usernamePassword(credentialsId: 'GitHubCredentials', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
    sh "rm -rf <manifest-repo-name>" // remove the repo if it already exists
    sh "git clone https://github.com/<github-username>/<manifest-repo-name>.git" // clone the repo
    sh "cd <manifest-repo-name>" // change directory to the repo
    dir('<manifest-repo-name>') { // change directory to the repo
    sh "sed -i 's/newTag.*/newTag: v${BUILD_NUMBER}/g' kustomize/overlays/*/*kustomization.yaml" // update the image version in the manifest
    sh "git config user.email [email protected]" // set git config
    sh "git config user.name devops-bot" // set git config
    sh "git add ${WORKSPACE}/<manifest-repo-name>/kustomize/overlays/*/*kustomization.yaml" // add the updated manifest to git
    sh "git commit -m 'Update image version to: ${BUILD_NUMBER}'" // commit the changes
    sh"git push https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/<github-username>/<manifest-repo-name>.git HEAD:master -f" // push changes
    }
    }
    }
    }

    In here we are using the withCredentials step to login to GitHub. You need to configure Jenkins with the necessary credentials to access the GitHub repository.

    Conclusion

    In this article, we learned how deploy a NodeJS application to Kubernetes using GitOps way by using Jenkins & ArgoCD. You can find the all the related commands for this tutorial from here and here. If you have any issue regarding this tutorial, mention your issue in the comment section or reach me through my E-mail.

    Happy Coding