End-to-End CI/CD Pipeline for a Node.js App using GitHub Actions


Introduction
In this blog post, I’ll walk you through building a complete CI/CD pipeline for a Node.js application using GitHub Actions. The pipeline covers:
Security scanning with Trivy and Gitleaks
Code quality analysis with SonarQube
Docker image build and push to Docker Hub
Docker image vulnerability scanning
Deployment to Kubernetes
All of this is automated using self-hosted GitHub Actions runners, enabling full control over the environment and resources.
Tools Used
TOOLS | PURPOSE |
Node.js | Backend application |
GitHub Actions | CI/CD Workflow automation |
SonarQube | Static code analysis and quality gate checks |
Trivy | Security scanning for vulnerabilities |
Gitleaks | Detects secrets like tokens or passwords in code |
Docker | Containerizes the application |
Kubernetes | Container orchestration |
Self-hosted GitHub Runner | For running jobs inside the network |
What Does This CI/CD Pipeline Workflow Do?
Here’s a high-level overview of the pipeline:
Performs security checks using Trivy and Gitleaks
SonarQube to analyse code quality
Builds and pushes a Docker image to Docker Hub
Deploys Application in to the Kubernetes cluster (in this project minikube)
Note: This entire workflow runs on the self-hosted runner and I used Minikube for creating the Kubernetes single node cluster.
Workflow Breakdown
Here’s a breakdown of each job defined in the CI/CD workflow :
Step 1: Security Scan
jobs:
Security_scan:
runs-on: self-hosted
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Trivy filesystem Scan
run: trivy fs --format table .
- name: Gitleaks Scan
run: gitleaks detect source . -f json
This Job scans the file system and gives the information about known vulnerabilities and the secrets if any present in the project.
Checkout Code
- For cloning the code into the GitHub Action runner machine. By using the actions/checkout action for the cloning the code.
Trivy Scan
- Trivy scan is used for the scanning the file system to find the known vulnerabilities in the project.
Gitleaks Scan
- Gitleaks is used to scan the code to check any accidentally committed secrets (like API keys or passwords).
Step 2: SonarQube Code Quality Analysis
Sonar_scan:
runs-on: self-hosted
needs: Security_scan
steps:
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5.1.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
- name: SonarQube Quality Gate Check
uses: sonarsource/sonarqube-quality-gate-action@v1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
This job scans the code and provides a report on code quality.
SonarQube Scan
It performs a static code analysis of your project to detect bugs, vulnerabilities, code smells, security issues, and code coverage.
Generates a detailed report with metrics (e.g., technical debt, duplication, complexity).
SonarQube Quality Gate Check
Defines a set of pass/fail criteria that a project must meet to be considered "production-ready."
Determines if the code meets the required quality standards.
Fails the build(in CI/CD) if conditions are not met.
Note: Store your SONAR_TOKEN (secret) and SONAR_HOST_URL (variable) securely in your GitHub repository settings under Secrets and Variables.
Step 3: Docker Image Build and Push
Image_build:
runs-on: self-hosted
needs: Sonar_scan
env:
IMAGE_NAME: node-app
IMAGE_TAG: latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Docker Login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Image Build and Push
uses: docker/build-push-action@v6
with:
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
- name: Trivy image scan
run: trivy image ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
This job is to build and push the Docker image, and scan the Docker image using the Trivy image scan.
Docker Login
- Using the action docker/login-action for login into Docker Hub or other image registry.
Buildx
- Buildx is used for building the Docker image
Image Build and Push
- This step is for building and pushing the docker image into the docker hub registry.
Trivy Image Scan
- This step is used to scan the Docker image using the Trivy Image scan to find the vulnerabilities.
Note: Store your DOCKER_USERNAME (variable) and DOCKER_PASSWORD (secret) securely in your GitHub repository settings under Secrets and Variables.
Step 4: Kubernetes Deployment
K8s_Deploy:
runs-on: self-hosted
needs: Image_build
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Deploy to k8s
run: kubectl apply -f ./kubernetes/.
This job is to apply Kubernetes manifest to deploy in to the cluster.
Deploy to k8s
- Runs the command kubectl apply for deploying the application into the cluster
Conclusion
In this blog post, we explored how to set up a complete CI/CD pipeline for a Node.js application using GitHub Actions and a self-hosted runner. From running security scans with Trivy and Gitleaks to ensuring code quality with SonarQube, containerizing the application with Docker, and deploying it to Kubernetes, all the essential DevOps stages were covered.
What I Did Before
Subscribe to my newsletter
Read articles from Charan Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
