Skip to main content

Command Palette

Search for a command to run...

End to End DevSecOps Project for DevOps Engineers.

Published
5 min readView as Markdown
P

👋 Hello, and welcome to my DevOps journey! 🚀 I am Priyanka Varshney,🛠️ As an aspiring DevOps engineer, I'm all about bridging the gap between development and operations, making software delivery seamless and efficient. 💻🔧 On this Hashnode blog, I'll be sharing my learnings, experiences and adventures as I dive deep into the world of continuous integration, automation, and cloud technologies. ☁️⚙️ Let's connect, learn, and grow as a vibrant DevOps community. Follow my Hashnode blog, and let's embrace the DevOps adventure together! 🤝🔗

In this project, we will learn about DevOps and DevSecOps tools in one project:

Tools Covered:

  • Linux

  • Git and GitHub

  • Docker

  • Docker-compose

  • Jenkins CI/CD

  • SonarQube

  • OWASP

  • Trivy

Pre-requisites to implement this project:

  • AWS EC2 instance (Ubuntu) with instance type t2.large and root volume 15GB.

  • Java and Jenkins installed:https://www.jenkins.io/doc/book/installing/linux/#long-term-support-release

  • Docker and docker-compose installed:

          sudo apt-get update
          sudo apt-get install docker.io -y
          sudo apt-get install docker-compose -y
    
  • Trivy installed:

    Install Trivy

      sudo apt-get install wget apt-transport-https gnupg lsb-release
    
      wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
    
      echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
    
      sudo apt-get update
    
      sudo apt-get install trivy
    
  • SonarQube Server installed

      docker run -itd --name sonarqube-server -p 9000:9000 sonarqube:lts-community
    

    Now you need to open the port 9000 and access using ipaddress:9000

  • To containerize the application, begin by creating separate Dockerfiles for the frontend and backend. These Dockerfiles will define the environment setup, dependencies, and commands needed to run each service inside its own container.

    Dockerfile for Frontend:

      # ------------------- Stage 1: Build Stage ------------------------------
      FROM node:21 AS frontend-builder
    
      # Set the working directory to /app
      WORKDIR /app
    
      # Copy the package.json and package-lock.json for dependency installation
      COPY package*.json ./
    
      # Install dependencies
      RUN npm install
    
      # Copy the rest of the application code
      COPY . .
    
      # ------------------- Stage 2: Final Stage ------------------------------
      FROM node:21-slim
    
      # Set the working directory to /app
      WORKDIR /app
    
      # Copy built assets and dependencies from frontend-builder stage
      COPY --from=frontend-builder /app .
    
      # Copy the .env.sample file to .env.local
      COPY .env.docker .env.local
    
      # Expose port 5173 for the Node.js application
      EXPOSE 5173
    
      # Define the default command to run the application in development mode
      CMD ["npm", "run", "dev", "--", "--host"]
    

    Dockerfile for Backend:

      # Stage 1
      FROM node:21 AS backend-builder
    
      # setup the working dir
      WORKDIR /app
    
      # code
      COPY . .
    
      # packages install
      RUN npm i
    
      # tests
      RUN npm run test
    
      # Stage 2
      FROM node:21-slim
    
      # setup the working dir
      WORKDIR /app
    
      # copy the above stage as compressed
      COPY --from=backend-builder /app .
    
      COPY .env.docker .env
    
      # Port
      EXPOSE 8080
    
      # App
      CMD ["npm", "start"]
    

    Once both Dockerfiles are ready, you’ll need to create a docker-compose.yml file. This file helps you define and manage multi-container Docker applications. With Docker Compose, you can run both the frontend and backend containers simultaneously, configure networking between them, and even manage volumes or environment variables in a centralized manner.

      version: "3.8"
      services:
        mongodb:
          container_name: mongo-service
          image: mongo:latest
          volumes:
            - ./backend/data:/data
          ports:
            - "27017:27017"
    
        backend:
          container_name: backend
          build: ./backend
          env_file:
            - ./backend/.env.docker
          ports:
            - "31100:8080"
          depends_on:
            - mongodb
    
        frontend:
          container_name: frontend
          build: ./frontend
          env_file:
            - ./frontend/.env.docker
          ports:
            - "5173:5173"
    
        redis:
          container_name: redis-service
          restart: unless-stopped
          image: redis:7.0.5-alpine 
          expose:
              - 6379
          depends_on:
            - mongodb
    
      volumes:
        data:
    

    Steps for Jenkins CI/CD:

    1. Access Jenkins UI with IPaddress:8080 and setup Jenkins

2. Go to Manage Jenkins, click on Plugins and install all the plugins listed below, we will require for other tools integration:

  • SonarQube Scanner (Version2.16.1)

  • Sonar Quality Gates (Version1.3.1)

  • OWASP Dependency-Check (Version5.4.3)

  • Docker (Version1.5)

  1. Open SonarQube and create a webhook.
    Navigate to the SonarQube dashboard, then go to Administration » Configuration » Webhooks to add a new webhook by entering a name and provide Jenkins URL followed by /sonarqube-webhook

  1. Generate a personal access token.
    Go to SonarQube » My Account » Security (accessible via the 3-line menu at the top right), then create a new token to use for authentication by entering a Token name.

  1. In Jenkins, go to "Manage Jenkins" > "System", then add your SonarQube server under the "SonarQube Servers" section by entering a name for the SonarQube server and provide its URL.

  1. In Jenkins Add SonarQube Scanner , go to “Tools “ and add the SonarQube Scanner by entering the name and click on install automatically.

    1. In Jenkins Add Dependency Check , go to “Tools “ and add the Dependency Check by entering the name and click on install automatically.

      1. Create a job

        Step 1: Create a New Job

        • Go to Jenkins Dashboard → New Item

        • Enter job name: DevSecOps-CICD

        • Choose Pipeline

        • Click OK

Step 2: Configure Pipeline

  • In the General section:

    • Add a description

    • Check GitHub Project and enter repo URL

  • In the Build Triggers:

    • Check GitHub hook trigger for GITScm polling
  • In Pipeline section:

    • Definition: Pipeline script

    • Paste the same script as in the console (below)

            pipeline{
                agent any
                environment {
                    SONARQUBE_ENV = tool 'SonarScanner' //should be same as sonarScanner
                }
                stages{
                    stage("Code clone from github"){
                        steps{
                           git url: "https://github.com/var-priya/Wanderlust_with_DevSecOps.git", branch:"main"
                         }
                    }
                    stage("SonarQube Analysis"){
                         steps{
                           withSonarQubeEnv("Sonar"){   //should be same as sonar server 
                                sh "$SONARQUBE_ENV/bin/sonar-scanner -Dsonar.projectKey=wanderlust -Dsonar.projectKey=wanderlust"
                            }
                         }
                    }
                    stage("Owasp dependency check"){
                         steps{
                           dependencyCheck additionalArguments:'--scan ./' , odcInstallation: 'Owasp'
                           dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
                         }
                    }
                    stage("Sonar Quality Gate Scan"){
                         steps{
                           timeout(time: 2, unit: 'MINUTES'){
                               waitForQualityGate abortPipeline: false
                           }
                         }
                    }
                    stage("Trivy File system Scan"){
                         steps{
                           sh "trivy fs --format table -o trivy-fs-report.html"
                         }
                    }
                    stage("Deploy using docker compose "){
                         steps{
                           sh "docker-compose up -d"
                         }
                    }

             }
            }
  • Step 3: Save and Build

    • Click Save

    • Click Build Now to trigger the pipeline manually
      Or trigger from GitHub using webhook

Note: The OWASP stage may take some time to complete, as it performs a thorough security scan to identify vulnerabilities in the application's dependencies and codebase.

Since OWASP Dependency-Check performs a deep analysis of all third-party libraries and compares them against known CVE databases, it can take several minutes, especially for large projects.

  • Verify the Deployment:

    To access the application, open your browser and visit:

       http:// IPaddress:5173
    

    Now you can create the post:

Now you can see the post :

  • Conclusion

    Congratulations! 🎉 Your Wanderlust application is now up and running on Jenkins with security tools. If you encounter any issues along the way, be sure to check the logs or consult the troubleshooting guide.
    Wishing you smooth deployments and happy coding! 🚀

More from this blog

Untitled Publication

39 posts