Maven, NPM, and Gradle โ how build tools power CI/CD pipelines for Spring Boot, Node.js, and React applications.
8
Chapters
3
Tools
100%
Free
01๐จ
Why Build Tools Matter
The Bridge Between Code and Deployment
As a DevOps engineer, you don't write the application code โ but you build, test, package, and deploy it. Build tools automate this entire process, and understanding them is essential for CI/CD pipelines.
What Build Tools Do
๐ฅ
Dependency Management
Automatically download libraries your app needs โ no manual JAR/package downloads.
๐ง
Compilation
Convert source code (Java, TypeScript) into executable format (bytecode, JS bundles).
๐งช
Testing
Run unit tests, integration tests, and code quality checks automatically.
You don't need to know how to write Java or React. You need to know: which command builds it, what artifact it produces, and how to deploy that artifact.
02โ
Maven for Spring Boot
Java Build Lifecycle & pom.xml
Maven is the standard build tool for Java/Spring Boot projects. It uses a pom.xml file to define dependencies, plugins, and build configuration. Every Spring Boot microservice you encounter in production likely uses Maven.
Maven Build Lifecycle
$ mvn validateCheck project structure is correct
$ mvn compileCompile source code to bytecode (.class files)
$ mvn testRun unit tests (JUnit, Mockito)
$ mvn packageCreate JAR/WAR file in target/ directory
$ mvn verifyRun integration tests
$ mvn installInstall artifact to local Maven repository (~/.m2)
$ mvn deployUpload artifact to remote repository (Nexus/Artifactory)
groupId + artifactId + version uniquely identifies every dependency. Like a package address.
๐
target/ Directory
Where Maven puts compiled classes and the final JAR/WAR. Add to .gitignore.
๐
~/.m2/repository
Local cache of downloaded dependencies. Saves re-downloading on every build.
๐ข
Nexus / Artifactory
Company-hosted Maven repository. Stores your team's private JAR files and caches public ones.
๐ก Spring Boot Fat JAR
mvn package on a Spring Boot project produces a fat JAR (~30-80MB) that contains the app + all dependencies + an embedded Tomcat server. Just run: java -jar app.jar
03โ๏ธ
Maven in CI/CD Pipelines
Jenkins, GitHub Actions & Docker
In a CI/CD pipeline, Maven compiles, tests, and packages your Spring Boot app automatically on every Git push. The output JAR is then containerized with Docker and deployed.
Jenkinsfile for Spring Boot
JENKINSFILEpipeline {
agent any
tools { maven 'Maven-3.9' }
stages {
stage('Checkout') {
steps { git branch: 'main', url: 'https://github.com/org/api-service.git' }
}
stage('Build & Test') {
steps { sh 'mvn clean package -DskipTests=false' }
}
stage('SonarQube Analysis') {
steps { sh 'mvn sonar:sonar -Dsonar.host.url=http://sonar:9000' }
}
stage('Docker Build') {
steps {
sh 'docker build -t api-service:${BUILD_NUMBER} .'
sh 'docker push ecr-repo/api-service:${BUILD_NUMBER}'
}
}
stage('Deploy to K8s') {
steps { sh 'kubectl set image deployment/api api=ecr-repo/api-service:${BUILD_NUMBER}' }
}
}
}
$ mvn versions:display-dependency-updatesCheck for newer dependency versions
โ ๏ธ Never Skip Tests in CI
Using -DskipTests in production pipelines defeats the purpose of CI. Only skip tests for emergency hotfixes, and add a manual approval gate.
04๐ฆ
NPM for Node.js & React
Package Management & Scripts
NPM (Node Package Manager) handles dependencies and build scripts for Node.js backends (Express, NestJS) and React/Next.js frontends. The package.json file is the equivalent of Maven's pom.xml.
Essential NPM Commands
$ npm init -yCreate a new package.json
$ npm installInstall all dependencies from package.json
Uses exact versions from lock file, deletes node_modules first
๐ก Always Use npm ci in CI
npm install can produce different node_modules on different machines. npm ci guarantees reproducible builds by strictly following package-lock.json. This is critical for CI/CD.
05๐
NPM in CI/CD Pipelines
Build React & Node.js Apps for Production
React frontends get built into static files (HTML/JS/CSS) and served by Nginx or S3. Node.js backends run as processes managed by PM2, or containerized in Docker. Both flow through CI/CD.
React App CI/CD Pipeline
PIPELINE# CI Pipeline for React Frontend
- Step 1: npm ci # Install exact dependencies
- Step 2: npm run lint # Code quality check
- Step 3: npm test -- --coverage # Run tests with coverage
- Step 4: npm run build # Creates build/ folder
- Step 5: aws s3 sync build/ s3://my-frontend-bucket
- Step 6: aws cloudfront create-invalidation # Clear CDN cache
Node.js Backend CI/CD Pipeline
PIPELINE# CI Pipeline for Express/NestJS Backend
- Step 1: npm ci # Install exact dependencies
- Step 2: npm test # Run unit + integration tests
- Step 3: docker build -t api . # Containerize
- Step 4: docker push ecr/api:v1 # Push to registry
- Step 5: kubectl rollout restart deployment/api # Deploy to K8s
React Build Output
๐
build/ or dist/
Static HTML, JS, CSS files โ ready to serve from any web server or CDN.
๐
Bundle Size Matters
Large bundles = slow page loads. Use code splitting, tree shaking, and lazy loading.
๐
Static Hosting
Deploy to S3 + CloudFront, Vercel, Netlify, or Nginx. No Node.js server needed for React.
Node.js Production Checklist
โUse npm ci (not npm install) in CI/CD pipelines
โSet NODE_ENV=production for optimized runtime
โUse PM2 or Docker for process management (never bare node server.js)
โPin dependency versions in package-lock.json
โRun npm audit regularly for security vulnerabilities
โUse multi-stage Docker builds to reduce image size
06๐
Gradle Basics
Modern Alternative to Maven
Gradle is a faster, more flexible build tool used by Android, Spring Boot, and many modern Java/Kotlin projects. It uses Groovy or Kotlin DSL instead of XML.
Maven vs Gradle
Feature
Maven
Gradle
Config Format
XML (pom.xml)
Groovy/Kotlin (build.gradle)
Speed
Slower (no caching)
Faster (incremental builds + cache)
Flexibility
Convention-over-config
Highly customizable
Learning Curve
Easier for beginners
Steeper but more powerful
Market Share
~60% Java projects
~40% and growing
build.gradle for Spring Boot
BUILD.GRADLEplugins {
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
id 'java'
}
group = 'com.devopsclicks'
version = '1.0.0'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Gradle Commands
$ ./gradlew buildCompile + test + package (use wrapper!)
$ ./gradlew bootJarCreate executable Spring Boot JAR
๐ก Gradle Wrapper
Always use ./gradlew (not gradle). The wrapper script ensures everyone uses the exact same Gradle version. Commit gradlew + gradle/wrapper/ to Git.
07๐ณ
Dockerizing Build Outputs
Multi-Stage Builds for Production
The final step in most CI/CD pipelines is containerizing the build output. Multi-stage Docker builds keep images small by separating the build environment from the runtime.
Spring Boot Dockerfile (Multi-Stage)
DOCKERFILE# Stage 1: Build with Maven
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Run with slim JRE
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
React Dockerfile (Multi-Stage)
DOCKERFILE# Stage 1: Build with Node
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Serve with Nginx
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
Node.js Backend Dockerfile
DOCKERFILEFROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
App Type
Build Output
Docker Base Image
Final Size
Spring Boot
target/app.jar
eclipse-temurin:17-jre-alpine
~180MB
React
build/ static files
nginx:alpine
~25MB
Node.js
node_modules + code
node:20-alpine
~150MB
08๐ผ
Interview Questions
Build Tools for DevOps Interviews
Common interview questions about build tools, CI/CD integration, and artifact management.
โ
What does mvn package do?
Compiles source code, runs tests, and creates a JAR/WAR file in the target/ directory. For Spring Boot, it creates a fat JAR with embedded Tomcat.
โ
npm install vs npm ci?
npm install may update lock file and versions. npm ci uses exact lock file versions and is reproducible. Always use npm ci in CI/CD pipelines.
โ
What is a Maven fat JAR?
A JAR that contains the application + all dependencies + embedded server. You can run it with java -jar app.jar without installing anything else.
โ
What is a multi-stage Docker build?
Uses one stage to build (with full SDK) and another to run (with slim runtime). Reduces final image size dramatically.
โ
Maven lifecycle phases?
validate โ compile โ test โ package โ verify โ install โ deploy. Each phase runs all previous phases automatically.
โ
What is package-lock.json?
Records exact dependency versions for reproducible builds. Must be committed to Git. npm ci relies on it entirely.
โ
Gradle vs Maven?
Gradle is faster (caching, incremental builds), more flexible (Groovy/Kotlin DSL), but has steeper learning curve. Maven is simpler but slower.
โ
Where are Maven artifacts stored?
Locally in ~/.m2/repository. Remotely in Nexus or Artifactory. Maven Central is the public repository.
โKnow which build command produces which artifact for each stack
โAlways use npm ci in CI/CD (not npm install)
โUse multi-stage Docker builds to minimize image size
โNever skip tests in production CI pipelines
โUnderstand Maven lifecycle phases (compile โ test โ package)
โCommit package-lock.json and gradlew to Git
โUse Nexus/Artifactory for private artifact storage