From 173293efaa4a8000e07f012943662a987e7ad0dc Mon Sep 17 00:00:00 2001 From: tusuii Date: Thu, 19 Feb 2026 18:09:25 +0530 Subject: [PATCH] added required k8s and docker file --- .dockerignore | 14 +++ .gitignore | 3 + Dockerfile | 40 +++++++++ k8s/base/configmap.yaml | 21 +++++ k8s/base/deployment.yaml | 87 +++++++++++++++++++ k8s/base/ingress.yaml | 21 +++++ k8s/base/kustomization.yaml | 16 ++++ k8s/base/mongodb-pvc.yaml | 11 +++ k8s/base/mongodb-service.yaml | 12 +++ k8s/base/mongodb-statefulset.yaml | 53 +++++++++++ k8s/base/namespace.yaml | 4 + k8s/base/postgres-pvc.yaml | 11 +++ k8s/base/postgres-service.yaml | 12 +++ k8s/base/postgres-statefulset.yaml | 59 +++++++++++++ k8s/base/service.yaml | 13 +++ k8s/overlays/local/kustomization.yaml | 14 +++ .../local/patches/deployment-patch.yaml | 14 +++ 17 files changed, 405 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 k8s/base/configmap.yaml create mode 100644 k8s/base/deployment.yaml create mode 100644 k8s/base/ingress.yaml create mode 100644 k8s/base/kustomization.yaml create mode 100644 k8s/base/mongodb-pvc.yaml create mode 100644 k8s/base/mongodb-service.yaml create mode 100644 k8s/base/mongodb-statefulset.yaml create mode 100644 k8s/base/namespace.yaml create mode 100644 k8s/base/postgres-pvc.yaml create mode 100644 k8s/base/postgres-service.yaml create mode 100644 k8s/base/postgres-statefulset.yaml create mode 100644 k8s/base/service.yaml create mode 100644 k8s/overlays/local/kustomization.yaml create mode 100644 k8s/overlays/local/patches/deployment-patch.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b473011 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +node_modules/ +*.log +logs/ +.env +.env.* +!.env.example +.git/ +.gitignore +k8s/ +.vscode/ +.idea/ +coverage/ +uploads/ +*.md diff --git a/.gitignore b/.gitignore index f82d99b..c6c506f 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,9 @@ Thumbs.db # Prisma prisma/migrations/ +# Kubernetes secrets (never commit real values) +k8s/base/secret.yaml + # Uploads (if storing locally) uploads/ public/uploads/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8e9d830 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +# ── Stage 1: builder ─────────────────────────────────────────────── +FROM node:18-alpine AS builder +WORKDIR /app +COPY package.json package-lock.json ./ +COPY prisma ./prisma/ +RUN npm ci --no-audit --no-fund +RUN npx prisma generate + +# ── Stage 2: production ──────────────────────────────────────────── +FROM node:18-alpine AS production +ENV NODE_ENV=production +WORKDIR /app + +# Non-root user +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + +# Production-only npm dependencies +COPY package.json package-lock.json ./ +RUN npm ci --omit=dev --no-audit --no-fund + +# Copy generated Prisma client from builder +COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma +# Copy prisma CLI so init container can run 'prisma migrate deploy' +COPY --from=builder /app/node_modules/prisma ./node_modules/prisma +COPY --from=builder /app/node_modules/.bin/prisma ./node_modules/.bin/prisma + +# Copy app source + Prisma schema/migrations +COPY src ./src +COPY prisma ./prisma + +# Temp uploads dir (emptyDir volume mounted here in k8s) +RUN mkdir -p uploads + +USER appuser +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD wget -qO- http://localhost:3000/health || exit 1 + +CMD ["node", "src/server.js"] diff --git a/k8s/base/configmap.yaml b/k8s/base/configmap.yaml new file mode 100644 index 0000000..68f50f9 --- /dev/null +++ b/k8s/base/configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: app-config + namespace: ecommerce +data: + NODE_ENV: "production" + PORT: "3000" + HOST: "0.0.0.0" + JWT_EXPIRES_IN: "7d" + JWT_REFRESH_EXPIRES_IN: "30d" + AWS_REGION: "us-east-1" + AWS_S3_BUCKET: "e-commerce" + AWS_ENDPOINT: "s3.sahasrarameta.tech" + AWS_PORT: "443" + AWS_SSL: "true" + PAYTM_WEBSITE: "WEBSTAGING" + PAYTM_CHANNEL_ID: "WEB" + PAYTM_INDUSTRY_TYPE: "Retail" + PAYTM_HOST: "securegw-stage.paytm.in" + FRONTEND_URL: "http://localhost:5173" diff --git a/k8s/base/deployment.yaml b/k8s/base/deployment.yaml new file mode 100644 index 0000000..43355bd --- /dev/null +++ b/k8s/base/deployment.yaml @@ -0,0 +1,87 @@ +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: + - name: wait-for-postgres + image: postgres:15-alpine + command: + - sh + - -c + - | + until pg_isready -h postgres -p 5432 -U vaishnavi; do + echo "Waiting for PostgreSQL..."; sleep 3 + done + - name: wait-for-mongodb + image: mongo:7 + command: + - sh + - -c + - | + until mongosh --host mongodb --port 27017 \ + --eval "db.adminCommand('ping')" --quiet; do + echo "Waiting for MongoDB..."; sleep 3 + done + - name: run-migrations + image: ecommerce-backend:latest + command: + - sh + - -c + - npx prisma migrate deploy + envFrom: + - secretRef: + name: app-secret + env: + - name: NODE_ENV + value: "production" + containers: + - name: ecommerce-app + image: ecommerce-backend:latest + ports: + - containerPort: 3000 + name: http + envFrom: + - configMapRef: + name: app-config + - secretRef: + name: app-secret + volumeMounts: + - name: uploads-volume + 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-volume + emptyDir: {} diff --git a/k8s/base/ingress.yaml b/k8s/base/ingress.yaml new file mode 100644 index 0000000..f8ee834 --- /dev/null +++ b/k8s/base/ingress.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ecommerce-ingress + namespace: ecommerce + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/proxy-body-size: "10m" + nginx.ingress.kubernetes.io/proxy-read-timeout: "60" +spec: + rules: + - host: api.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: ecommerce-app + port: + number: 80 diff --git a/k8s/base/kustomization.yaml b/k8s/base/kustomization.yaml new file mode 100644 index 0000000..7995e6c --- /dev/null +++ b/k8s/base/kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: ecommerce +resources: + - namespace.yaml + - configmap.yaml + - secret.yaml + - postgres-pvc.yaml + - postgres-statefulset.yaml + - postgres-service.yaml + - mongodb-pvc.yaml + - mongodb-statefulset.yaml + - mongodb-service.yaml + - deployment.yaml + - service.yaml + - ingress.yaml diff --git a/k8s/base/mongodb-pvc.yaml b/k8s/base/mongodb-pvc.yaml new file mode 100644 index 0000000..a191dd1 --- /dev/null +++ b/k8s/base/mongodb-pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mongodb-data + namespace: ecommerce +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/k8s/base/mongodb-service.yaml b/k8s/base/mongodb-service.yaml new file mode 100644 index 0000000..c9af8f4 --- /dev/null +++ b/k8s/base/mongodb-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: mongodb + namespace: ecommerce +spec: + type: ClusterIP + selector: + app: mongodb + ports: + - port: 27017 + targetPort: 27017 diff --git a/k8s/base/mongodb-statefulset.yaml b/k8s/base/mongodb-statefulset.yaml new file mode 100644 index 0000000..9886ba4 --- /dev/null +++ b/k8s/base/mongodb-statefulset.yaml @@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: mongodb + namespace: ecommerce + labels: + app: mongodb +spec: + serviceName: mongodb + replicas: 1 + selector: + matchLabels: + app: mongodb + template: + metadata: + labels: + app: mongodb + spec: + securityContext: + fsGroup: 999 + containers: + - name: mongodb + image: mongo:7 + ports: + - containerPort: 27017 + env: + - name: MONGO_INITDB_DATABASE + value: "vaishnavi_products" + volumeMounts: + - name: mongodb-data + mountPath: /data/db + resources: + requests: + cpu: "100m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" + readinessProbe: + exec: + command: [mongosh, --eval, "db.adminCommand('ping')", --quiet] + initialDelaySeconds: 15 + periodSeconds: 5 + failureThreshold: 6 + livenessProbe: + exec: + command: [mongosh, --eval, "db.adminCommand('ping')", --quiet] + initialDelaySeconds: 30 + periodSeconds: 10 + volumes: + - name: mongodb-data + persistentVolumeClaim: + claimName: mongodb-data diff --git a/k8s/base/namespace.yaml b/k8s/base/namespace.yaml new file mode 100644 index 0000000..0c996fc --- /dev/null +++ b/k8s/base/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ecommerce diff --git a/k8s/base/postgres-pvc.yaml b/k8s/base/postgres-pvc.yaml new file mode 100644 index 0000000..f322106 --- /dev/null +++ b/k8s/base/postgres-pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-data + namespace: ecommerce +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/k8s/base/postgres-service.yaml b/k8s/base/postgres-service.yaml new file mode 100644 index 0000000..06951d8 --- /dev/null +++ b/k8s/base/postgres-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: ecommerce +spec: + type: ClusterIP + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 diff --git a/k8s/base/postgres-statefulset.yaml b/k8s/base/postgres-statefulset.yaml new file mode 100644 index 0000000..efb3e6a --- /dev/null +++ b/k8s/base/postgres-statefulset.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres + namespace: ecommerce + labels: + app: postgres +spec: + serviceName: postgres + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + securityContext: + fsGroup: 999 + 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 diff --git a/k8s/base/service.yaml b/k8s/base/service.yaml new file mode 100644 index 0000000..2c95e36 --- /dev/null +++ b/k8s/base/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: ecommerce-app + namespace: ecommerce +spec: + type: ClusterIP + selector: + app: ecommerce-app + ports: + - name: http + port: 80 + targetPort: 3000 diff --git a/k8s/overlays/local/kustomization.yaml b/k8s/overlays/local/kustomization.yaml new file mode 100644 index 0000000..c74d847 --- /dev/null +++ b/k8s/overlays/local/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: ecommerce +resources: + - ../../base +images: + - name: ecommerce-backend + newName: ecommerce-backend + newTag: latest +patches: + - path: patches/deployment-patch.yaml + target: + kind: Deployment + name: ecommerce-app diff --git a/k8s/overlays/local/patches/deployment-patch.yaml b/k8s/overlays/local/patches/deployment-patch.yaml new file mode 100644 index 0000000..da3f89a --- /dev/null +++ b/k8s/overlays/local/patches/deployment-patch.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ecommerce-app + namespace: ecommerce +spec: + template: + spec: + initContainers: + - name: run-migrations + imagePullPolicy: Never + containers: + - name: ecommerce-app + imagePullPolicy: Never