🎬 Video Walkthrough (YouTube): https://youtu.be/V_LmJB9ZXu0
This project is a 3-tier cloud-native Issue Tracker application deployed using a fully automated CI/CD pipeline.
Every push to main triggers GitHub Actions, which:
- Builds Docker images for the frontend and backend
- Pushes them to Amazon ECR
- Deploys them to Amazon EKS
- Updates the running application with zero downtime
This repository is excellent for learning real-world DevOps pipelines and modern Kubernetes deployments.
┌──────────────────┐
│ GitHub Repo │
└─────────┬────────┘
│ Push (main)
▼
┌──────────────────┐
│ GitHub Actions CI │
└───────┬──────────┘
Builds & Pushes │
Docker Images → ECR ▼
┌──────────────────────────────┐
│ AWS Elastic Container Reg. │
└──────────────┬──────────────┘
▼
┌──────────────────┐
│ AWS EKS │
└──────────────────┘
(Frontend | Backend | Mongo)
flowchart LR
A[Developer Push to main] --> B[GitHub Actions]
subgraph CI/CD Pipeline
B --> C[Build Docker Images]
C --> D[Push to Amazon ECR]
D --> E[Update kubeconfig]
E --> F[Deploy to EKS via kubectl]
end
subgraph AWS EKS Cluster
F --> G[Frontend Deployment\n(React + NGINX)]
F --> H[Backend Deployment\n(Node.js + Express)]
F --> I[MongoDB Deployment]
H --> I
G --> H
end
G --> J[(LoadBalancer Service)]
J --> K[End User Browser]
- Frontend: React + Vite
- Backend: Node.js + Express
- Database: MongoDB
- Clean UI for Issue creation + listing
- Fully containerized with Docker
- Kubernetes deployments for ALL services
- MongoDB deployed directly in cluster
- CI/CD using GitHub Actions
- ECR as image registry
- EKS (managed Kubernetes) for hosting
- Automatic application rollout on every push
- Namespaces + services + deployments
.
├── frontend/ # React app
├── backend/ # Express API
├── k8s/
│ ├── namespace.yml
│ ├── mongo-deployment.yml
│ ├── backend-deployment.yml
│ ├── frontend-deployment.yml
├── .github/workflows/
│ └── deploy.yml # GitHub Actions CI/CD pipeline
└── README.md
Pipeline runs on every push to main:
on:
push:
branches: [ "main" ]- Checkout repo
- Assume AWS IAM Role using OIDC
- Login to ECR
- Build & push Docker images
- Update kubeconfig for EKS
- Apply K8s manifests
- Update Deployment images using set image
- Wait for rollout
This guarantees zero-downtime deployment.
Both apps include lightweight production Dockerfiles:
FROM node:18-alpine
WORKDIR /app
COPY package*.json .
RUN npm install --production
COPY . .
EXPOSE 4000
CMD ["node", "src/server.js"]FROM node:18-alpine AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
FROM nginx:alpine
# Copy custom nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy built frontend
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Follow these steps exactly, in order.
From your local machine (with AWS CLI configured):
aws ecr create-repository \
--repository-name issue-tracker-frontend \
--region ap-south-1
aws ecr create-repository \
--repository-name issue-tracker-backend \
--region ap-south-1curl --silent --location "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" \
| tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl versionRun from your laptop:
eksctl create cluster \
--name issue-tracker-cluster \
--region ap-south-1 \
--nodegroup-name issue-tracker-nodes \
--node-type t3.small \
--nodes 2 \
--managedWhen finished, confirm:
kubectl get nodesIn AWS IAM → Identity providers → Add provider
- Provider: GitHub
- Audience: sts.amazonaws.com
Use “Web Identity” with the GitHub provider above.
Replace your-org and your-repo:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:nipun221/issue-tracker:ref:refs/heads/main"
}
}
}
]
}Attach:
- AmazonEC2ContainerRegistryFullAccess
- AmazonEKSClusterPolicy
- AmazonEKSWorkerNodePolicy
- AmazonEKS_CNI_Policy
- IAMReadOnlyAccess
- Custom inline allowing:
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster",
"eks:DescribeNodegroup",
"eks:ListClusters"
],
"Resource": "*"
}kubectl edit configmap aws-auth -n kube-systemPaste under mapRoles::
- rolearn: arn:aws:iam::<ACCOUNT_ID>:role/GitHubActionsEKSRole
username: github-actions
groups:
- system:mastersThis gives your GitHub workflow cluster admin for deployment.
Add these in Repository → Settings → Variables:
AWS_REGION = ap-south-1
AWS_ACCOUNT_ID = 15882564789
EKS_CLUSTER_NAME = issue-tracker-cluster
Push to main:
git add .
git commit -m "trigger deployment"
git pushGitHub Actions will:
- build images
- push to ECR
- update EKS manifests
- rollout updates
Your demo database uses emptyDir: (ephemeral).
Data resets when the Mongo pod is replaced.
Connects via DNS:
mongodb://mongo:27017/issue_tracker
Served via LoadBalancer Backend API resolved via cluster DNS.
Get the frontend URL:
kubectl get svc -n issue-trackerOpen in browser → create issues → watch app work end-to-end.
Run these in exact order:
kubectl delete namespace issue-trackereksctl delete cluster \
--name issue-tracker-cluster \
--region ap-south-1aws ecr delete-repository --repository-name issue-tracker-frontend --force --region ap-south-1
aws ecr delete-repository --repository-name issue-tracker-backend --force --region ap-south-1Manually delete GitHubActionsEKSRole in AWS console.
AWS recreates it automatically → leave it.
- GitHub Actions CI/CD
- AWS IAM Roles (OIDC)
- Pushing Docker images to ECR
- Deploying microservices to Kubernetes
- Managing multi-tier applications in EKS
- DNS-based service discovery
- Infrastructure as Code (EKSctl)
This motivates me to create more DevOps projects and tutorials.






