Jerney is a 3-tier blog application deployed on Kubernetes.
It has:
- Frontend: React app served by Nginx
- Backend: Node.js + Express API
- Database: PostgreSQL
This project shows how I built and deployed the full stack on Amazon EKS, while managing cloud infrastructure with Terraform.
The main goal of this project is to show practical DevOps skills:
- Containerizing each service
- Running multi-service workloads on Kubernetes
- Managing secrets and config properly
- Using persistent storage for database data
- Building cloud infrastructure as code (Terraform)
- Deploying the application on EKS
Client -> Frontend Service (Nginx/React) -> Backend Service (Express API) -> DB Service (PostgreSQL)
Inside Kubernetes:
- All workloads run in the
jerneynamespace - Each tier has its own Deployment and Service
- Backend and DB use internal ClusterIP networking
- Frontend is exposed through a NodePort
Resource:
- Service name:
jerney-deployment - Type:
NodePort - Port:
80(NodePort30000)
Responsibility:
- Serves the React UI to users
- Proxies all
/api/*requests to the backend service - Acts as the entry point to the application
How it works:
- User opens the frontend URL
- Nginx serves static UI files
- For API calls, Nginx forwards traffic to
jerney-backend:5000
Resource:
- Service name:
jerney-backend - Type: internal ClusterIP
- Port:
5000
Responsibility:
- Handles all blog APIs (posts and comments)
- Validates requests and runs business logic
- Connects to PostgreSQL using environment variables from ConfigMap/Secret
How it works:
- Receives API requests from frontend
- Reads/writes post and comment data in database
- Returns JSON responses to frontend
Resource:
- Service name:
db - Type: internal ClusterIP
- Port:
5432
Responsibility:
- Stores application data (posts, comments)
- Provides persistent storage through PVC
How it works:
- Only backend connects to it
- PostgreSQL data is mounted on persistent volume
- Data survives pod restarts
jerneynamespace isolates all project resources.
jerney-deployment: runs frontend containerbackend-deployment: runs backend containerpostgres-deployment: runs PostgreSQL container
- ConfigMap (
jerney-configmap) stores non-sensitive values like ports - Secret (
jerney-secrets) stores DB credentials and DB connection settings
- PersistentVolume (
jerney-pv) - PersistentVolumeClaim (
jerney-pvc)
These keep database data safe beyond pod lifecycle.
- User accesses frontend through NodePort.
- Frontend serves UI and sends API calls to
/api. - Nginx in frontend forwards
/apitraffic to backend service (jerney-backend). - Backend processes request and queries database via
dbservice. - Database returns data to backend.
- Backend sends response to frontend.
- Frontend shows result to user.
- Built frontend and backend as separate Docker images.
- Kept PostgreSQL as a dedicated data tier.
- Defined Kubernetes resources for namespace, deployments, services, secrets, configmap, and storage.
- Connected services using Kubernetes DNS names (
jerney-backend,db). - Added persistent volume claim for database durability.
- Added local
kindsetup for local Kubernetes testing. - Used Terraform to provision AWS networking and EKS cluster.
- Applied Kubernetes manifests to run the app on EKS.
Terraform code creates:
- VPC with public and private subnets
- NAT gateway for private subnet egress
- EKS cluster (Auto Mode)
- Cluster logging and encryption settings
- Required subnet tags for Kubernetes load balancing
This gives a repeatable and version-controlled cloud setup.
From terraform/:
terraform init
terraform plan
terraform applyaws eks update-kubeconfig --region ap-south-1 --name jerney-eksFrom project root:
kubectl apply -f k8s/namespace.yml
kubectl apply -f k8s/secrets.yml
kubectl apply -f k8s/configmap.yml
kubectl apply -f k8s/pv.yml
kubectl apply -f k8s/pvc.yml
kubectl apply -f k8s/postgres-deployment.yml
kubectl apply -f k8s/backend-deployment.yml
kubectl apply -f k8s/frontend-deployment.yml
kubectl apply -f k8s/services.ymlkubectl get pods -n jerney
kubectl get svc -n jerney
kubectl get pvc -n jerney- End-to-end 3-tier architecture deployment on Kubernetes
- Infrastructure as Code with Terraform for AWS + EKS
- Clear service boundaries and internal service communication
- Secure config handling with Secrets and ConfigMaps
- Persistent storage setup for database reliability
- Containerized workloads with clean separation of concerns
- Current Kubernetes manifests expose frontend using NodePort.
- For production internet exposure, an Ingress or LoadBalancer service is recommended.
- Image names in manifests currently use local tags (
latest); for shared environments, use a registry (for example, ECR).