A modern full-stack application demonstrating DevOps best practices with microservices architecture, featuring automated CI/CD pipelines, IaC(terraform), containerization, and Kubernetes orchestration.
This project consists of:
- DevOps Pipeline: Jenkins CI/CD with Docker and Kubernetes deployment
- Infrastructure as Code: Terraform for DigitalOcean Kubernetes cluster provisioning
- Orchestration: Kubernetes with blue-green deployment strategy
- Frontend: React.js application with user authentication and product management
- Microservices Backend:
- User Service: Node.js/Express API handling authentication and user management
- Commerce Service: Node.js/Express API managing products and orders
- Database: MongoDB for data persistence
- React.js
- Node.js - JavaScript runtime
- Express.js - Web application framework
- User Service - Authentication, user registration, and user management
- Commerce Service - Product catalog, order management, and inventory
- MongoDB - NoSQL database
- Mongoose - MongoDB object modeling
- JWT - JSON Web Tokens for authentication
- bcrypt - Password hashing
- CORS - Cross-origin resource sharing
- Terraform - Infrastructure as Code for cloud provisioning
- DigitalOcean - Cloud provider for Kubernetes clusters
- Docker - Containerization platform
- Kubernetes - Container orchestration
- Jenkins - CI/CD automation
- Docker Hub - Container registry
- Blue-Green Deployment - Zero-downtime deployment strategy
Before running this application, ensure you have the following installed:
- Node.js (v18 or higher)
- npm
- Docker
- Kubernetes (I use the one built into Docker Desktop)
- kubectl CLI tool
- Jenkins (I run it as a docker container )
- MongoDB (local or cloud instance)
- Terraform (for infrastructure provisioning)
- DigitalOcean Account (for cloud deployment)
If you want to deploy to a DigitalOcean Kubernetes cluster, use Terraform to provision the infrastructure:
Create a terraform.tfvars file in the terraform/ directory (or use the existing ones in terraform/tfvars/):
cd terraform
cp tfvars/dev.tfvars terraform.tfvars
# Edit the file with your specific values# Initialize Terraform
terraform init
# Plan the deployment
terraform plan -var-file="tfvars/dev.tfvars" -var="do_token=<your_digital_ocen_token>"
# Apply the infrastructure
terraform plan -var-file="tfvars/dev.tfvars" -var="do_token=<your_digital_ocen_token>"This will create:
- DigitalOcean Kubernetes cluster
- Node pools
- Load balancers
- Promethues operator and Grafana Dashboard
# Get cluster credentials
doctl kubernetes cluster kubeconfig save <cluster-name>This section will help you set up Jenkins with Docker integration to automate the build, test, and deployment pipeline.
First, create a Docker network for Jenkins:
docker network create jenkinsRun Jenkins as a Docker container:
docker run -d --name jenkins-blueocean \
--restart=on-failure \
--network jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueoceanAccess Jenkins Dashboard:
- Open your browser and go to
http://localhost:8080 - Install Docker plugins
Since Jenkins runs inside a Docker container, a Docker-in-Docker (DinD) setup is required to expose the host’s Docker socket. This allows Jenkins to access the local Docker engine and build Docker images during the CI/CD pipeline:
docker run -d --restart=always \
--name docker-socat \
-p 127.0.0.1:2376:2375 \
--network jenkins \
-v /var/run/docker.sock:/var/run/docker.sock \
alpine/socat tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sockGet the container's IP address:
docker inspect docker-socat | grep IPAddress-
In Jenkins Dashboard (
http://localhost:8080):- Go to Manage Jenkins → Clouds
- Click Configure Clouds → Add a new cloud → Docker
-
Docker Cloud Configuration:
- Docker Host URI:
tcp://<IP_FROM_STEP_3>:2375 - Test Connection to verify it works
- Enabled: ✓ (checked)
- Docker Host URI:
-
Add Docker Agent Template:
- Click Docker Agent templates → Add Docker Template
- Labels:
jenkins-docker-agent(must match Jenkinsfile) - Docker Image:
jenkins/agent:latest(Create the desired image) - Instance Capacity:
2 - Remote File System Root:
/home/jenkins
-
In Jenkins Dashboard:
- Go to Manage Jenkins → Manage Credentials
- Click System → Global credentials → Add Credentials
-
Add Docker Hub Credentials:
- Kind: Username with password
- Username: Your Docker Hub username
- Password: Your Docker Hub password/access token
- ID:
dockerhub-creds(must match Jenkinsfile) - Description: Docker Hub Credentials
If you want Jenkins to deploy to Kubernetes:
- Add Kubernetes Config:
- Kind: Secret file
- File: Upload your
~/.kube/configfile - ID:
kube-config-jenkins(must match Jenkinsfile) - Description: Kubernetes Config
-
Create User Service Pipeline:
- Go to New Item → Pipeline
- Name:
user-service-pipeline - Pipeline Definition: Pipeline script from SCM
- SCM: Git
- Repository URL: Your repository URL
- Script Path:
user-service/Jenkinsfile
-
Create Commerce Service Pipeline:
- Name:
commerce-service-pipeline - Script Path:
commerce-service/Jenkinsfile
- Name:
-
Create Frontend Pipeline:
- Name:
frontend-pipeline - Script Path:
frontend/Jenkinsfile
- Name:
Option 1: Automatic (SCM Polling):
- Pipelines will automatically run every 5 minutes if changes are detected
Option 2: Manual Trigger:
- Go to your pipeline → Click Build Now
- Ensure your Kubernetes cluster is running (local or provisioned via Terraform)
- Configure
kubectlto connect to your cluster - Edit the Kubernetes YAML files to reference the Docker images for the microservices that were pushed to Docker Hub
Before deploying the backend services, create a Kubernetes secret with your MongoDB connection string:
kubectl create secret generic backend-secret \
--from-literal=MONGODB_URI=<your_mongodb_atlas_connection_string>Replace <your_mongodb_atlas_connection_string> with your actual MongoDB Atlas connection string.
# Deploy blue version
kubectl apply -f k8s/user-service/user-blue-deployment.yaml
kubectl apply -f k8s/user-service/user-clusterIP.yaml
# Deploy green version (for blue-green deployment)
kubectl apply -f k8s/user-service/user-green-deployment.yaml# Deploy blue version
kubectl apply -f k8s/commerce-service/commerce-blue-deployment.yaml
kubectl apply -f k8s/commerce-service/commerce-clusterIP.yaml
# Deploy green version (for blue-green deployment)
kubectl apply -f k8s/commerce-service/commerce-green-deployment.yamlkubectl apply -f k8s/frontend/frontend-deployment.yaml
kubectl apply -f k8s/frontend/frontend-clusterIP.yamlkubectl get pods
kubectl get services
kubectl get deploymentsTo enable HTTPS for your application, you'll need to create a TLS certificate and Kubernetes secret for the ingress controller.
mkdir my-cert && cd my-certopenssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-out tls.crt -keyout tls.key \
-subj "/CN=myapp.local/O=myapp.local"This creates two files:
tls.crt→ Public TLS certificatetls.key→ Private key for the certificate
To verify the files exist:
lskubectl create secret tls myapp-tls --key tls.key --cert tls.crtMake sure your ingress YAML file references the TLS secret
echo "127.0.0.1 myapp.local" | sudo tee -a /etc/hostskubectl apply -f k8s/ingress.yamlNow you can access your application securely at https://myapp.local
This project includes automated Jenkins pipelines for frontend and both microservices:
- Build: Creates Docker image with version tagging
- Test: Validates container functionality
- Push: Publishes image to Docker Hub
- Deploy: Implements blue-green deployment strategy
- Build: Creates Docker image with version tagging
- Test: Validates container functionality
- Push: Publishes image to Docker Hub
- Deploy: Implements blue-green deployment strategy
- Build: Creates optimized production build
- Test: Validates container startup
- Push: Publishes to container registry
- Deploy: Updates Kubernetes deployment
- Automatic: SCM polling every 5 minutes
- Manual: Jenkins job execution
- Webhook: Git repository changes (if configured)
POST /users/signup- Register new userPOST /users/login- User authenticationGET /users/profile- Get user profile (authenticated)PUT /users/profile- Update user profile (authenticated)
GET /products/all-products- Get all productsPOST /products/create-product- Create new product (authenticated)POST /orders/create-order- Create new order (authenticated)GET /orders/user-orders- Get user's orders (authenticated)
- Serves the React.js application
- Handles routing and user interface
- Communicates with both microservices via API calls
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Commit changes:
git commit -am 'Add new feature' - Push to branch:
git push origin feature/new-feature - Submit a Pull Request