diff --git a/k8s/README.md b/k8s/README.md deleted file mode 100644 index 6be1e98a..00000000 --- a/k8s/README.md +++ /dev/null @@ -1,267 +0,0 @@ -# 🚀 Full-Stack Chat App Deployment Guide: Kubernetes (Kind) & Docker Compose - -Welcome to the official guide for deploying a **Full-Stack Chat Application** on your local machine. Whether you're a student, a professional, or someone exploring the world of Kubernetes and Docker, this guide is designed to help you deploy the app with ease. - -In this tutorial, you will learn how to: -1. Set up a local Kubernetes environment using **Kind**. -2. Deploy a **Full-Stack Chat Application** (Frontend, Backend, MongoDB) on **Kubernetes**. -3. Explore an alternative deployment using **Docker Compose**. - ---- - -## 📋 Prerequisites - -Before we start the deployment, ensure that you have the following tools installed and set up on your machine: - -### **1. Kind (Kubernetes in Docker)** -Kind is a tool that lets you run Kubernetes clusters in Docker containers. It’s lightweight, easy to use, and perfect for local development. - -**For Windows** (PowerShell): -```bash -curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.25.0/kind-windows-amd64 -Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe -``` - -**For Windows** (WSL - Windows Subsystem for Linux): -```bash -# For AMD64 / x86_64 -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-amd64 - -# For ARM64 -[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-arm64 -chmod +x ./kind -sudo mv ./kind /usr/local/bin/kind -``` - -**For Linux**: -```bash -# For AMD64 / x86_64 -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-amd64 - -# For ARM64 -[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-linux-arm64 -chmod +x ./kind -sudo mv ./kind /usr/local/bin/kind -``` - ---- - -### **2. Kubectl (Kubernetes Command Line Tool)** -Kubectl is the tool we’ll use to manage Kubernetes clusters. You’ll use it to interact with your local Kubernetes cluster and deploy resources. - -**For x86_64 Architecture:** -```bash -curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" -``` - -**For ARM64 Architecture:** -```bash -curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl" -``` - -**Validate the downloaded binary:** -```bash -curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" -echo "$(cat kubectl.sha256) kubectl" | sha256sum --check -``` - -**Install kubectl:** -```bash -sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl -# OR if there’s an issue with your root permissions: -chmod +x kubectl -mkdir -p ~/.local/bin -mv ./kubectl ~/.local/bin/kubectl -``` - -**Verify kubectl installation:** -```bash -kubectl version --client --output=yaml -``` - ---- - -### **3. Docker** -Docker is required for building and running containers locally. Follow the instructions on the [official Docker website](https://www.docker.com/get-started) to download and install Docker on your system. - -Once installed, you can verify Docker by running: - -```bash -docker --version -``` - ---- - -## 🛠️ Cloning the Project - -With the prerequisites set up, let’s grab the code for the chat application. Run the following commands: - -```bash -git clone https://github.com/iemafzalhassan/full-stack_chatApp.git -``` -```bash -cd full-stack_chatApp/k8s -``` - -```bash -git checkout DevOps -``` - -This will: -- **Clone** the project repository from GitHub. -- Navigate into the `k8s` folder, which contains the Kubernetes configuration files for the deployment. - ---- - -## 🚢 Deployment Using Kubernetes (Kind) - -Now that we have everything in place, let’s start deploying the chat application to Kubernetes. Below are the detailed steps to deploy each component of the application using **Kind**. - -### 1. Create Kind Cluster: - -```bash -# Create cluster using config - -kind create cluster --config k8s/kind-config.yaml - -# Verify cluster is running -kubectl cluster-info -``` - -### 2. Create Namespace and Base Resources - -A **namespace** is a way to organize your resources. It keeps the app's resources isolated and easy to manage. To create the namespace for our chat app, run: - - -```bash -# Create namespace -kubectl apply -f k8s/namespace.yaml - -# Verify namespace creation -kubectl get namespaces -``` - -### 3. Create Storage and Configurations - -MongoDB is used for storing chat messages and user data. To deploy MongoDB, apply the following commands: - -```bash -# Create MongoDB PVC -kubectl apply -f k8s/mongo-pvc.yaml -n chat-app - -# Create backend secrets -kubectl apply -f k8s/backend-secrets.yaml -n chat-app - -# Create frontend nginx config -kubectl apply -f k8s/frontend-configmap.yaml -n chat-app -``` - -### 4. Deploy MongoDB -```bash -# Deploy MongoDB -kubectl apply -f k8s/mongodb-deployment.yaml -n chat-app -kubectl apply -f k8s/mongodb-service.yaml -n chat-app - -# Wait for MongoDB pod to be ready -kubectl wait --for=condition=Ready pods -l app=mongodb -n chat-app --timeout=120s -``` - - -### 5. 🖥️ Deploy Backend Service - -The **backend** service processes messages and user authentication. To deploy the backend, run the following commands: - -```bash -# Deploy Backend -kubectl apply -f k8s/backend-deployment.yaml -n chat-app -kubectl apply -f k8s/backend-service.yaml -n chat-app - -# Wait for Backend pod to be ready -kubectl wait --for=condition=Ready pods -l app=backend -n chat-app --timeout=120s -``` - -These files will deploy the backend service, which will handle all API requests from the frontend. - -### 6. 🌐 Deploy Frontend Service - -The **frontend** is the user interface where people interact with the chat app. To deploy the frontend, use these commands: - -```bash -# Deploy Frontend -kubectl apply -f k8s/frontend-deployment.yaml -n chat-app -kubectl apply -f k8s/frontend-service.yaml -n chat-app - -# Wait for Frontend pod to be ready -kubectl wait --for=condition=Ready pods -l app=frontend -n chat-app --timeout=120s -``` - -This will launch the frontend UI and expose it to the web. - ---- - -## 🧐 Verification and Management - -Once the app is deployed, it's crucial to verify that everything is running smoothly. - -```bash -# Check all resources -kubectl get all -n chat-app - -# Check pod logs if needed -kubectl logs -f -l app=frontend -n chat-app -kubectl logs -f -l app=backend -n chat-app -kubectl logs -f -l app=mongodb -n chat-app -``` -## Accessing the Application - -The application is exposed through NodePort services: -http://localhost:8080 - -You can verify the service URLs using: -```bash -# Get service details -kubectl get svc -n chat-app -``` - -### 🔍 Describe a Pod - -If a pod isn’t working as expected, you can describe it to get more information: - -```bash -kubectl describe pod -n chat-app -``` - -This will give you detailed information about a specific pod, including any potential issues. - -## Cleanup - -When you're done, you can clean up using: -```bash -# Delete all resources in namespace -kubectl delete namespace chat-app - -# Delete the kind cluster -kind delete cluster --name chat-app-cluster -``` - ---- - -## 🐳 Docker Compose (Alternative Local Deployment) - -If you prefer a simpler local setup using **Docker Compose**, you can deploy the chat app without Kubernetes. Here’s how to do it: - -```bash -docker-compose up -d --build -``` - -This command: -- Starts all services defined in the `docker-compose.yml` file. -- Runs the services in detached mode (`-d`). -- Rebuilds the Docker images (`--build`) in case of any changes. - -Once the services are running, you can access the app at [http://localhost:8080](http://localhost:8080). - - -## 🎉 Conclusion - -Congratulations! You’ve successfully deployed the **Full-Stack Chat Application** using **Kubernetes (via Kind)** or **Docker Compose**. Whether you're using Kubernetes for a more robust, scalable solution or Docker Compose for a simpler local setup, your chat app is now running! diff --git a/k8s/backend-deployment.yaml b/k8s/backend-deployment.yaml index 0bf7e56f..fa68ab9d 100644 --- a/k8s/backend-deployment.yaml +++ b/k8s/backend-deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: backend + name: backend-deployment namespace: chat-app spec: replicas: 1 @@ -10,31 +10,25 @@ spec: app: backend template: metadata: + name: backend-pod + namespace: chat-app labels: app: backend spec: containers: - - name: backend - image: iemafzal/backend:v1 - imagePullPolicy: Always - ports: - - containerPort: 5001 - env: - - name: MONGODB_URI - value: "mongodb://root:admin@mongodb:27017/chatApp?authSource=admin" - - name: PORT - value: "5001" - - name: NODE_ENV - value: "production" - - name: JWT_SECRET - valueFrom: - secretKeyRef: - name: backend-secrets - key: jwt-secret - resources: - limits: - memory: "512Mi" - cpu: "500m" - requests: - memory: "256Mi" - cpu: "250m" \ No newline at end of file + - name: chatapp-backend + image: polepallivarun/chatapp-backend:latest + ports: + - containerPort: 5001 + env: + - name: MONGODB_URI + value: "mongodb://mongoadmin:secret123@mongodb-service:27017/chatapp?authSource=admin&retryWrites=true&w=majority" + - name: PORT + value: "5001" + - name: NODE_ENV + value: production + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: chatapp-secrets + key: jwt-secret \ No newline at end of file diff --git a/k8s/backend-secrets.yaml b/k8s/backend-secrets.yaml deleted file mode 100644 index 92a80f8a..00000000 --- a/k8s/backend-secrets.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: backend-secrets - namespace: chat-app -type: Opaque -stringData: - jwt-secret: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE3MzQ3MjA5MzAsImV4cCI6MTc2NjI1NjkzMCwiYXVkIjoidHJhaW53aXRoc2h1YmhhbS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiR2l2ZW5OYW1lIjoiQWZ6YWwiLCJTdXJuYW1lIjoiUm9ja2V0IiwiRW1haWwiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiUm9sZSI6WyJEZXZPcHMiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.ehelBbUU2IFJ8M5xzQL_UFatMxCMSojAOqWQaZQgrwk" \ No newline at end of file diff --git a/k8s/backend-service.yaml b/k8s/backend-service.yaml index e77be197..36d67dbd 100644 --- a/k8s/backend-service.yaml +++ b/k8s/backend-service.yaml @@ -7,8 +7,5 @@ spec: selector: app: backend ports: - - protocol: TCP - port: 5001 - targetPort: 5001 - nodePort: 30501 - type: NodePort + - port: 5001 + targetPort: 5001 \ No newline at end of file diff --git a/k8s/frontend-configmap.yaml b/k8s/frontend-configmap.yaml deleted file mode 100644 index 2792a83c..00000000 --- a/k8s/frontend-configmap.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: nginx-config - namespace: chat-app -data: - nginx.conf: | - server { - listen 80; - server_name localhost; - - root /usr/share/nginx/html; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - - location /api/ { - proxy_pass http://backend.chat-app.svc.cluster.local:5001/api/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } - - location /socket.io/ { - proxy_pass http://backend.chat-app.svc.cluster.local:5001/socket.io/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; - } - } \ No newline at end of file diff --git a/k8s/frontend-deployment.yaml b/k8s/frontend-deployment.yaml index 4c5f013b..ffa3cb80 100644 --- a/k8s/frontend-deployment.yaml +++ b/k8s/frontend-deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: frontend + name: frontend-deployment namespace: chat-app spec: replicas: 1 @@ -10,45 +10,16 @@ spec: app: frontend template: metadata: + name: frontend-pod + namespace: chat-app labels: app: frontend spec: containers: - - name: frontend - image: iemafzal/frontend:v1 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 80 - env: - - name: NODE_ENV - value: "production" - - name: BACKEND_URL - value: "http://backend:5001" - readinessProbe: - httpGet: - path: / - port: 80 - initialDelaySeconds: 30 - periodSeconds: 10 - failureThreshold: 3 - livenessProbe: - httpGet: - path: / - port: 80 - initialDelaySeconds: 20 - periodSeconds: 15 - volumeMounts: - - name: nginx-config - mountPath: /etc/nginx/conf.d/default.conf - subPath: nginx.conf - resources: - limits: - memory: "256Mi" - cpu: "200m" - requests: - memory: "128Mi" - cpu: "100m" - volumes: - - name: nginx-config - configMap: - name: nginx-config \ No newline at end of file + - name: chatapp-frontend + image: polepallivarun/chatapp-frontend:latest + ports: + - containerPort: 80 + env: + - name: NODE_ENV + value: production \ No newline at end of file diff --git a/k8s/frontend-service.yaml b/k8s/frontend-service.yaml index ff6f33e9..a4a84913 100644 --- a/k8s/frontend-service.yaml +++ b/k8s/frontend-service.yaml @@ -7,8 +7,5 @@ spec: selector: app: frontend ports: - - protocol: TCP - port: 80 - targetPort: 80 - nodePort: 30080 - type: NodePort + - port: 80 + targetPort: 80 \ No newline at end of file diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 00000000..0db45f2c --- /dev/null +++ b/k8s/ingress.yaml @@ -0,0 +1,29 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: chatapp-myingress + namespace: chat-app + labels: + name: chatapp-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - host: chatapp.example.com + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: frontend + port: + number: 80 + - pathType: Prefix + path: "/api" + backend: + service: + name: backend + port: + number: 5001 diff --git a/k8s/kind-config.yaml b/k8s/kind-config.yaml deleted file mode 100644 index 9dbe92e2..00000000 --- a/k8s/kind-config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -name: chat-app-cluster -nodes: -- role: control-plane - extraPortMappings: - - containerPort: 30080 - hostPort: 8080 - - containerPort: 30501 - hostPort: 5001 - - containerPort: 27017 - hostPort: 27017 diff --git a/k8s/mongo-persistentvolume.yaml b/k8s/mongo-persistentvolume.yaml new file mode 100644 index 00000000..8afea0f6 --- /dev/null +++ b/k8s/mongo-persistentvolume.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: monogo-pv + namespace: chat-app +spec: + accessModes: + - ReadWriteOnce + capacity: + storage: 5Gi + hostPath: + path: /data \ No newline at end of file diff --git a/k8s/mongo-pvc.yaml b/k8s/mongo-persistentvolumeclaim.yaml similarity index 77% rename from k8s/mongo-pvc.yaml rename to k8s/mongo-persistentvolumeclaim.yaml index 6ebff1ce..aa27788a 100644 --- a/k8s/mongo-pvc.yaml +++ b/k8s/mongo-persistentvolumeclaim.yaml @@ -8,5 +8,4 @@ spec: - ReadWriteOnce resources: requests: - storage: 1Gi - storageClassName: standard \ No newline at end of file + storage: 5Gi \ No newline at end of file diff --git a/k8s/mongodb-service.yaml b/k8s/mongo-service.yaml similarity index 52% rename from k8s/mongodb-service.yaml rename to k8s/mongo-service.yaml index 04959c3e..fc3b6df8 100644 --- a/k8s/mongodb-service.yaml +++ b/k8s/mongo-service.yaml @@ -1,13 +1,11 @@ apiVersion: v1 kind: Service metadata: - name: mongodb + name: mongodb-service namespace: chat-app spec: selector: app: mongodb ports: - - protocol: TCP - port: 27017 - targetPort: 27017 - type: ClusterIP \ No newline at end of file + - port: 27017 + targetPort: 27017 diff --git a/k8s/mongodb-deployment.yaml b/k8s/mongodb-deployment.yaml index 1a39e483..34bbbfef 100644 --- a/k8s/mongodb-deployment.yaml +++ b/k8s/mongodb-deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: mongodb + name: mongodb-deployment namespace: chat-app spec: replicas: 1 @@ -10,23 +10,22 @@ spec: app: mongodb template: metadata: + name: mongodb-pod + namespace: chat-app labels: app: mongodb spec: containers: - - name: mongodb - image: iemafzal/mongodb:v1 - ports: - - containerPort: 27017 - env: - - name: MONGO_INITDB_ROOT_USERNAME - value: root - - name: MONGO_INITDB_ROOT_PASSWORD - value: admin - volumeMounts: - - name: mongo-data - mountPath: /data/db + - name: chatapp-mongodb + image: mongo:latest + ports: + - containerPort: 27017 + env: + - name: MONGO_INITDB_ROOT_USERNAME + value: mongoadmin + - name: MONGO_INITDB_ROOT_PASSWORD + value: secret123 volumes: - - name: mongo-data - persistentVolumeClaim: - claimName: mongo-pvc \ No newline at end of file + - name: mongo-storage + persistentVolumeClaim: + claimName: mongo-pvc \ No newline at end of file diff --git a/k8s/namespace.yaml b/k8s/namespace.yaml index df6f44da..f56bc397 100644 --- a/k8s/namespace.yaml +++ b/k8s/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: chat-app + name: chat-app \ No newline at end of file diff --git a/k8s/secrets.yaml b/k8s/secrets.yaml new file mode 100644 index 00000000..c603275a --- /dev/null +++ b/k8s/secrets.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: chatapp-secrets + namespace: chat-app +type: Opaque +data: + jwt-secret: ODI2MVRKSDFzaHFkREpKdU9ERE9VVHVWTldMTkFJN3ZBck9yRnJ2c1lSdA==