added required k8s and docker file
This commit is contained in:
14
.dockerignore
Normal file
14
.dockerignore
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
node_modules/
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
k8s/
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
coverage/
|
||||||
|
uploads/
|
||||||
|
*.md
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -118,6 +118,9 @@ Thumbs.db
|
|||||||
# Prisma
|
# Prisma
|
||||||
prisma/migrations/
|
prisma/migrations/
|
||||||
|
|
||||||
|
# Kubernetes secrets (never commit real values)
|
||||||
|
k8s/base/secret.yaml
|
||||||
|
|
||||||
# Uploads (if storing locally)
|
# Uploads (if storing locally)
|
||||||
uploads/
|
uploads/
|
||||||
public/uploads/
|
public/uploads/
|
||||||
|
|||||||
40
Dockerfile
Normal file
40
Dockerfile
Normal file
@@ -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"]
|
||||||
21
k8s/base/configmap.yaml
Normal file
21
k8s/base/configmap.yaml
Normal file
@@ -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"
|
||||||
87
k8s/base/deployment.yaml
Normal file
87
k8s/base/deployment.yaml
Normal file
@@ -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: {}
|
||||||
21
k8s/base/ingress.yaml
Normal file
21
k8s/base/ingress.yaml
Normal file
@@ -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
|
||||||
16
k8s/base/kustomization.yaml
Normal file
16
k8s/base/kustomization.yaml
Normal file
@@ -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
|
||||||
11
k8s/base/mongodb-pvc.yaml
Normal file
11
k8s/base/mongodb-pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mongodb-data
|
||||||
|
namespace: ecommerce
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
12
k8s/base/mongodb-service.yaml
Normal file
12
k8s/base/mongodb-service.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mongodb
|
||||||
|
namespace: ecommerce
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: mongodb
|
||||||
|
ports:
|
||||||
|
- port: 27017
|
||||||
|
targetPort: 27017
|
||||||
53
k8s/base/mongodb-statefulset.yaml
Normal file
53
k8s/base/mongodb-statefulset.yaml
Normal file
@@ -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
|
||||||
4
k8s/base/namespace.yaml
Normal file
4
k8s/base/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: ecommerce
|
||||||
11
k8s/base/postgres-pvc.yaml
Normal file
11
k8s/base/postgres-pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: postgres-data
|
||||||
|
namespace: ecommerce
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
12
k8s/base/postgres-service.yaml
Normal file
12
k8s/base/postgres-service.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
namespace: ecommerce
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
59
k8s/base/postgres-statefulset.yaml
Normal file
59
k8s/base/postgres-statefulset.yaml
Normal file
@@ -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
|
||||||
13
k8s/base/service.yaml
Normal file
13
k8s/base/service.yaml
Normal file
@@ -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
|
||||||
14
k8s/overlays/local/kustomization.yaml
Normal file
14
k8s/overlays/local/kustomization.yaml
Normal file
@@ -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
|
||||||
14
k8s/overlays/local/patches/deployment-patch.yaml
Normal file
14
k8s/overlays/local/patches/deployment-patch.yaml
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user