CI / CD Next step is awesome!

CI / CD Next step is awesome!

Alright, so if you followed along the previous post, you know I have setup Jenkins to kind of run continuous integration. Well, I have now pushed it a bit further.

I installed a docker image of SonarQube (the community edition) and wow, do I have only one regret: I should have started with all of this setup on day one.

My flow is now this:

So, in a nutshell, what is VERY COOL is that when I push code on my develop branch, this happens automatically:

  • unit tests are triggered
  • code analysis is triggered

And in SonarQube code analysis, I found bunch of interesting suggestions, enhancements and bug fixes. They were not necessarily product-breaking, but I found many things I was not even aware of. My future code will just be better.

CD pipeline?

I also added a CD pipeline for my test environment. I am not ready yet to put quality gates to automate production deployment, but I am on the right track! Here is my current CD pipeline:

It is quite simple, but it works just perfect!

Now, I was wondering if this would be too much for my server. You know, running all of these:

  • Verdaccio docker image (npm private repository)
  • Jenkins docker image (CI/CD pipelines)
  • SonarQube docker image (code analysis)
  • 3 Tests docker images (React frontend, Node backend, Service manager)
  • 3 Production docker images (same as just before)
  • Nginx docker image (reverse proxy)
  • Prometheus & Grafana (directly, not docker images) for system monitoring

Here’s what happens:

More or less: NOTHING.

Well, not enough to be concerned about it yet. Of course, there’s not a lot of users, but I expect even with a few dozen of users, it wouldn’t be so bad. And if this became really serious, the production environments would be hosted on the cloud somewhere for 100% uptime (at least as a target).

To be honest, the tough part was to get the correct Jenkinsfile structure – just because I am not used to it. For safe keeping, I am writing my two pipelines here, and who knows, maybe it can help you too!

CI pipelines – Jenkinsfile

pipeline {
    agent any
    tools {nodejs "node"} 
    stages {
        stage('Install dependencies') { 
            steps {
                sh 'npm install' 
            }
        }
        stage('Unit Tests') { 
            steps {
                sh 'npm run test' 
            }
        }
        stage('SonarQube Analysis') {
            steps{
                script {
                    def scannerHome = tool 'sonar-scanner';
                    withSonarQubeEnv('local-sonarqube') {
                        withCredentials([string(credentialsId: 'sonar-secret', variable: 'SONAR_TOKEN')]) {
                            sh "${scannerHome}/bin/sonar-scanner -Dsonar.login=\$SONAR_TOKEN"
                        }
                    }
                }
            }
        }
    }
}

CD Pipeline Jenkinsfile

pipeline {
    agent any

    stages {
        stage('Verify Docker is available') {
            steps {
                script {
                    sh 'docker version'
                }
            }
        }
        stage('Copy .env and config file') {
            steps {
                script {
                    configFileProvider([configFile(fileId: 'frontend-dev.env', variable: 'DEV_ENV')]) {
                        sh 'cp $DEV_ENV .env'
                    }
                }
                script {
                    configFileProvider([configFile(fileId: 'frontend-custom-config.js', variable: 'DEV_CONFIG')]) {
                        sh 'cp $DEV_CONFIG ./src/config.js'
                    }
                }
            }
        }
        stage('Build Dev') {
            steps {
                sh 'docker build -t frontend:develop .'
            }
        }
        stage('Stop and Remove previous Container') {
            steps {
                sh 'docker stop frontend-develop || true'
                sh 'docker rm frontend-develop || true'
            }
        }
        stage('Start Dev') {
            steps {
                sh 'docker run --name frontend-develop -d -p 3033:3033 -e PORT=3033 frontend:develop'
            }
        }
    }
}

Next step: fixes all the identified issues by SonarQube. When I am done with that, I will begin the CD for prod.