From 4b26a49776fc103b6845f67f499161cd6b6ed39e Mon Sep 17 00:00:00 2001 From: tusuii Date: Thu, 19 Feb 2026 19:34:26 +0530 Subject: [PATCH] k8s --- 00-namespace.yaml | 4 ++ 01-postgres.yaml | 86 ++++++++++++++++++++++++++++++ 02-redis.yaml | 59 +++++++++++++++++++++ 03-backend-secret.yaml | 41 ++++++++++++++ 04-backend-configmap.yaml | 35 ++++++++++++ 05-backend.yaml | 109 ++++++++++++++++++++++++++++++++++++++ 06-website.yaml | 80 ++++++++++++++++++++++++++++ 07-admin-panel.yaml | 81 ++++++++++++++++++++++++++++ 8 files changed, 495 insertions(+) create mode 100644 00-namespace.yaml create mode 100644 01-postgres.yaml create mode 100644 02-redis.yaml create mode 100644 03-backend-secret.yaml create mode 100644 04-backend-configmap.yaml create mode 100644 05-backend.yaml create mode 100644 06-website.yaml create mode 100644 07-admin-panel.yaml diff --git a/00-namespace.yaml b/00-namespace.yaml new file mode 100644 index 0000000..0c996fc --- /dev/null +++ b/00-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ecommerce diff --git a/01-postgres.yaml b/01-postgres.yaml new file mode 100644 index 0000000..f484c51 --- /dev/null +++ b/01-postgres.yaml @@ -0,0 +1,86 @@ +# PostgreSQL — PersistentVolumeClaim + Deployment + Service +# Credentials match the env file: user=vaishnavi pass=admin db=vaishnavi_db +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-data + namespace: ecommerce +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + # If your cluster has no default StorageClass, add: storageClassName: "local-path" + # For k3s clusters this is already set to local-path by default. +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres + namespace: ecommerce + labels: + app: postgres +spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:15-alpine + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + value: "vaishnavi_db" + - name: POSTGRES_USER + value: "vaishnavi" + - name: POSTGRES_PASSWORD + value: "admin" + - name: PGDATA + value: "/var/lib/postgresql/data/pgdata" + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + resources: + requests: + cpu: "100m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" + readinessProbe: + exec: + command: ["pg_isready", "-U", "vaishnavi", "-d", "vaishnavi_db"] + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 6 + livenessProbe: + exec: + command: ["pg_isready", "-U", "vaishnavi", "-d", "vaishnavi_db"] + initialDelaySeconds: 30 + periodSeconds: 10 + volumes: + - name: postgres-data + persistentVolumeClaim: + claimName: postgres-data +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: ecommerce +spec: + type: ClusterIP + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 diff --git a/02-redis.yaml b/02-redis.yaml new file mode 100644 index 0000000..7b5bbb2 --- /dev/null +++ b/02-redis.yaml @@ -0,0 +1,59 @@ +# Redis — Deployment + Service +# Used by the backend for BullMQ job queues. +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: ecommerce + labels: + app: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:7-alpine + ports: + - containerPort: 6379 + command: ["redis-server", "--appendonly", "yes"] + resources: + requests: + cpu: "50m" + memory: "64Mi" + limits: + cpu: "200m" + memory: "256Mi" + readinessProbe: + exec: + command: ["redis-cli", "ping"] + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 3 + livenessProbe: + exec: + command: ["redis-cli", "ping"] + initialDelaySeconds: 15 + periodSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: ecommerce + labels: + app: redis +spec: + type: ClusterIP + selector: + app: redis + ports: + - port: 6379 + targetPort: 6379 diff --git a/03-backend-secret.yaml b/03-backend-secret.yaml new file mode 100644 index 0000000..6ed7e94 --- /dev/null +++ b/03-backend-secret.yaml @@ -0,0 +1,41 @@ +# Backend Secrets — plain text via stringData (k8s base64-encodes them automatically) +# +# BEFORE APPLYING: +# - Replace JWT_SECRET and JWT_REFRESH_SECRET with strong random strings +# - DATABASE_URL points to the in-cluster postgres service (do not change the hostname) +# - MONGODB_URI uses MongoDB Atlas (cloud) — taken directly from the env file +# - REDIS_URL points to the in-cluster redis service (do not change the hostname) +# - Update PAYTM_CALLBACK_URL with your actual backend Node IP and NodePort (30300) +--- +apiVersion: v1 +kind: Secret +metadata: + name: backend-secret + namespace: ecommerce +type: Opaque +stringData: + # PostgreSQL — in-cluster service "postgres" on port 5432 + DATABASE_URL: "postgresql://vaishnavi:admin@postgres:5432/vaishnavi_db?schema=public" + + # MongoDB Atlas — cloud hosted, taken from env file + MONGODB_URI: "mongodb+srv://techintern_db_user:LiIb5oaof93wx0MY@cluster0.bnv4nae.mongodb.net/vaishnavi_products" + + # Redis — in-cluster service "redis" on port 6379 + REDIS_URL: "redis://redis:6379" + + # JWT — replace these with strong secrets before deploying to production + JWT_SECRET: "your-super-secret-jwt-key-change-this-in-production" + JWT_REFRESH_SECRET: "your-refresh-token-secret" + + # AWS S3 / MinIO — taken from env file + AWS_ACCESS_KEY_ID: "uA7WvT9fhydcozyz5alo" + AWS_SECRET_ACCESS_KEY: "AusEy6KKqanQQU3Zw3rXYBaiS5BM8aPoAKfpcbFr" + + # Email (Gmail SMTP app password) + EMAIL_USER: "vaibhav.sahasrara@gmail.com" + EMAIL_PASS: "pezjcxfnegguzkuh" + + # Paytm — update PAYTM_CALLBACK_URL with real node IP + PAYTM_MERCHANT_ID: "your_merchant_id" + PAYTM_MERCHANT_KEY: "abcd1234abcd1234" + PAYTM_CALLBACK_URL: "http://:30300/api/payments/paytm/callback" diff --git a/04-backend-configmap.yaml b/04-backend-configmap.yaml new file mode 100644 index 0000000..7479031 --- /dev/null +++ b/04-backend-configmap.yaml @@ -0,0 +1,35 @@ +# Backend ConfigMap — non-sensitive configuration +# +# BEFORE APPLYING: +# Replace with the actual IP of any node in your cluster. +# Run: kubectl get nodes -o wide to find the IP. +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: backend-config + namespace: ecommerce +data: + NODE_ENV: "production" + PORT: "3000" + HOST: "0.0.0.0" + + JWT_EXPIRES_IN: "7d" + JWT_REFRESH_EXPIRES_IN: "30d" + + # AWS S3 / MinIO + AWS_REGION: "us-east-1" + AWS_S3_BUCKET: "e-commerce" + AWS_ENDPOINT: "s3.sahasrarameta.tech" + AWS_PORT: "443" + AWS_SSL: "true" + + # Paytm + PAYTM_WEBSITE: "WEBSTAGING" + PAYTM_CHANNEL_ID: "WEB" + PAYTM_INDUSTRY_TYPE: "Retail" + PAYTM_HOST: "securegw-stage.paytm.in" + + # Frontend origin — replace with your cluster node's IP + FRONTEND_URL: "http://:30800" + CORS_ORIGIN: "http://:30800" diff --git a/05-backend.yaml b/05-backend.yaml new file mode 100644 index 0000000..2a13cce --- /dev/null +++ b/05-backend.yaml @@ -0,0 +1,109 @@ +# Backend — Deployment + NodePort Service +# +# BEFORE APPLYING: +# Set the image to your built image, e.g.: +# youruser/ecommerce-backend:latest (Docker Hub) +# registry.local:5000/ecommerce-backend:latest (local registry) +# +# The init containers: +# 1. wait-for-postgres — polls until PostgreSQL is accepting connections +# 2. run-migrations — runs "prisma migrate deploy" once postgres is up +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ecommerce-app + namespace: ecommerce + labels: + app: ecommerce-app +spec: + replicas: 1 + selector: + matchLabels: + app: ecommerce-app + template: + metadata: + labels: + app: ecommerce-app + spec: + initContainers: + # Waits until PostgreSQL is ready before running migrations + - name: wait-for-postgres + image: postgres:15-alpine + imagePullPolicy: IfNotPresent + command: + - sh + - -c + - | + until pg_isready -h postgres -p 5432 -U vaishnavi; do + echo "Waiting for PostgreSQL..."; sleep 3 + done + echo "PostgreSQL is ready." + + # Runs Prisma migrations — uses the same backend image + - name: run-migrations + image: ecommerce-backend:latest # <-- same image as the main container + imagePullPolicy: IfNotPresent + command: ["sh", "-c", "npx prisma migrate deploy"] + envFrom: + - secretRef: + name: backend-secret + env: + - name: NODE_ENV + value: "production" + + containers: + - name: ecommerce-app + image: ecommerce-backend:latest # <-- replace with your registry image + imagePullPolicy: IfNotPresent + ports: + - containerPort: 3000 + name: http + envFrom: + - configMapRef: + name: backend-config + - secretRef: + name: backend-secret + volumeMounts: + - name: uploads + mountPath: /app/uploads + resources: + requests: + cpu: "250m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" + readinessProbe: + httpGet: + path: /health + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /health + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 20 + failureThreshold: 3 + + volumes: + - name: uploads + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: ecommerce-app + namespace: ecommerce +spec: + type: NodePort + selector: + app: ecommerce-app + ports: + - name: http + port: 3000 + targetPort: 3000 + nodePort: 30300 # Access via http://:30300 diff --git a/06-website.yaml b/06-website.yaml new file mode 100644 index 0000000..4fd3290 --- /dev/null +++ b/06-website.yaml @@ -0,0 +1,80 @@ +# eCommerce Customer Website — Deployment + NodePort Service +# +# BEFORE BUILDING THE IMAGE: +# The API URL is baked into the JS bundle at Docker build time by Vite. +# You MUST build the image with the real backend URL: +# +# docker build \ +# --build-arg VITE_API_BASE_URL=http://:30300/api \ +# -t ecommerce-web:latest \ +# ./eCommerce-website +# +# BEFORE APPLYING: +# Set image: to your built image name. +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ecommerce-web + namespace: ecommerce + labels: + app: ecommerce-web +spec: + replicas: 2 + selector: + matchLabels: + app: ecommerce-web + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + template: + metadata: + labels: + app: ecommerce-web + spec: + containers: + - name: ecommerce-web + image: ecommerce-web:latest # <-- replace with your registry image + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + resources: + requests: + cpu: "100m" + memory: "64Mi" + limits: + cpu: "250m" + memory: "128Mi" + readinessProbe: + httpGet: + path: /healthz + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /healthz + port: 80 + initialDelaySeconds: 10 + periodSeconds: 15 + failureThreshold: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: ecommerce-web + namespace: ecommerce + labels: + app: ecommerce-web +spec: + type: NodePort + selector: + app: ecommerce-web + ports: + - name: http + port: 80 + targetPort: 80 + nodePort: 30800 # Access via http://:30800 diff --git a/07-admin-panel.yaml b/07-admin-panel.yaml new file mode 100644 index 0000000..9c798c3 --- /dev/null +++ b/07-admin-panel.yaml @@ -0,0 +1,81 @@ +# eCommerce Admin Panel — Deployment + NodePort Service +# +# BEFORE BUILDING THE IMAGE: +# VITE_API_URL is baked into the JS bundle at Docker build time. +# You MUST build the image with the real backend URL: +# +# docker build \ +# --build-arg VITE_API_URL=http://:30300/api \ +# --build-arg VITE_APP_NAME="VC E-Commerce Admin Panel" \ +# -t ecommerce-admin-panel:latest \ +# ./eCommerce-admin-panel +# +# BEFORE APPLYING: +# Set image: to your built image name. +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ecommerce-admin-panel + namespace: ecommerce + labels: + app: ecommerce-admin-panel +spec: + replicas: 2 + selector: + matchLabels: + app: ecommerce-admin-panel + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + template: + metadata: + labels: + app: ecommerce-admin-panel + spec: + containers: + - name: ecommerce-admin-panel + image: ecommerce-admin-panel:latest # <-- replace with your registry image + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + resources: + requests: + cpu: "50m" + memory: "64Mi" + limits: + cpu: "200m" + memory: "128Mi" + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 10 + periodSeconds: 15 + failureThreshold: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: ecommerce-admin-panel + namespace: ecommerce + labels: + app: ecommerce-admin-panel +spec: + type: NodePort + selector: + app: ecommerce-admin-panel + ports: + - name: http + port: 80 + targetPort: 80 + nodePort: 30801 # Access via http://:30801