# End to End DevSecOps Project for DevOps Engineers.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746002196858/7d9ad22b-7f76-4bbe-9725-b9986904ddac.png align="center")

### **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](https://www.jenkins.io/doc/book/installing/linux/#long-term-support-release)
    
* Docker and docker-compose installed:
    
    ```plaintext
        sudo apt-get update
        sudo apt-get install docker.io -y
        sudo apt-get install docker-compose -y
    ```
    
* Trivy installed:
    
    Install Trivy
    
    ```plaintext
    sudo apt-get install wget apt-transport-https gnupg lsb-release
    ```
    
    ```plaintext
    wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
    ```
    
    ```plaintext
    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
    ```
    
    ```plaintext
    sudo apt-get update
    ```
    
    ```plaintext
    sudo apt-get install trivy
    ```
    
* SonarQube Server installed
    
    ```plaintext
    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
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745924359405/caedf50e-9cef-4e6a-97d0-2a0d2604d083.png align="center")
    
* 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:**
    
    ```plaintext
    # ------------------- 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:**
    
    ```plaintext
    # 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.
    
    ```plaintext
    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
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745923892196/65b2a7fa-1cf7-49e6-a8cb-4656c652b205.png align="center")
        

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)
    

3. **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
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745927377458/5a86ce73-2f70-41e9-8f42-7f8bd1794d45.png align="center")

4. **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.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745927479851/514cd9ec-1118-4ec2-adb2-f1b053c06394.png align="center")

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745927712604/7e37949c-8bb3-4ce2-b58e-46f696b83277.png align="center")

6. In Jenkins Add SonarQube Scanner , go to “Tools “ and add the SonarQube Scanner by entering the name and click on install automatically.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745927937664/c0ec9720-4cef-4454-a8b8-4521483dae68.png align="center")
    
    7. In Jenkins Add Dependency Check , go to “Tools “ and add the Dependency Check by entering the name and click on install automatically.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745928256764/875b4b34-d309-4998-ab59-56b16258410f.png align="center")
        
        8. #### 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)
                    
            
            ```plaintext
            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.
                
                ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746000190982/149fc758-176c-474a-889e-c5062d64f764.png align="center")
                
                ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746006851371/5d566c82-a497-4938-8b3a-6cdfb0d8d227.png align="center")
                
                * ### **Verify the Deployment:**
                    
                    ### **To access the application, open your browser and visit:**
                    
                    ```plaintext
                     http:// IPaddress:5173
                    ```
                    
                    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746007376208/195fd362-f25e-48be-870f-95020b5412e6.png align="center")
                    
                    Now you can create the post:
                    
                * ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746007649060/b81ba80f-3cf7-4a87-a01c-9e2af459b2d1.png align="center")
                    
                
                Now you can see the post :
                
                ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1746007699419/c013946f-c773-4906-8584-f813f9b69858.png align="center")
                
                * ### 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! 🚀
