added k8s files and jenkinsfile

This commit is contained in:
tusuii
2026-03-10 22:39:47 +05:30
parent 74918d251f
commit 57a2968d74
22 changed files with 767 additions and 1 deletions

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: ecommerce

View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-configmap
namespace: ecommerce
data:
NODE_ENV: "production"
PORT: "3000"
SEND_REAL_WHATSAPP: "false"
MONGODB_URI: "mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products"
REDIS_URL: "redis://redis.database.svc.cluster.local:6379"
AWS_REGION: "us-east-1"
AWS_S3_BUCKET: "e-commerce"
AWS_ENDPOINT: "s3.sahasrarameta.tech"
AWS_PORT: "443"
AWS_SSL: "true"
JWT_EXPIRES_IN: "7d"
JWT_REFRESH_EXPIRES_IN: "30d"
FRONTEND_URL: "http://NODE_IP_PLACEHOLDER:30081"
CORS_ORIGIN: "http://NODE_IP_PLACEHOLDER:30081,http://NODE_IP_PLACEHOLDER:30082,https://vaishnavi-admin.myriadcara.in,https://vaishnavi-bakend.myriadcara.in,https://vaishnavi-test.myriadcara.in"
PAYTM_WEBSITE: "WEBSTAGING"
PAYTM_HOST: "securegw-stage.paytm.in"
PAYTM_CALLBACK_URL: "http://NODE_IP_PLACEHOLDER:30080/api/payments/paytm/callback"
WAPP_BASE_URL: "https://api.wappconnect.com"
WAPP_INSTANCE: "SSM"

View File

@@ -0,0 +1,45 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: ecommerce
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: 192.168.49.2:30004/vaishnavi-ecommerce/backend:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: backend-configmap
- secretRef:
name: backend-secret
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 15
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5

20
k8s/backend/ingress.yaml Normal file
View File

@@ -0,0 +1,20 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend-ingress
namespace: ecommerce
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
ingressClassName: nginx
rules:
- host: backend.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 3000

View File

@@ -0,0 +1,22 @@
apiVersion: batch/v1
kind: Job
metadata:
name: backend-migration
namespace: ecommerce
spec:
template:
spec:
containers:
- name: migration
image: 192.168.49.2:30004/vaishnavi-ecommerce/backend:latest
imagePullPolicy: Always
command:
- npx
- prisma
- db
- push
envFrom:
- secretRef:
name: backend-secret
restartPolicy: Never
backoffLimit: 3

17
k8s/backend/secret.yaml Normal file
View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Secret
metadata:
name: backend-secret
namespace: ecommerce
type: Opaque
data:
DATABASE_URL: cG9zdGdyZXNxbDovL3ZhaXNobmF2aTphZG1pbkBwb3N0Z3Jlcy5kYXRhYmFzZS5zdmMuY2x1c3Rlci5sb2NhbDo1NDMyL3ZhaXNobmF2aV9kYj9zY2hlbWE9cHVibGlj
JWT_SECRET: eW91ci1zdXBlci1zZWNyZXQtand0LWtleS1jaGFuZ2UtdGhpcy1pbi1wcm9kdWN0aW9u
JWT_REFRESH_SECRET: eW91ci1yZWZyZXNoLXRva2VuLXNlY3JldA==
AWS_ACCESS_KEY_ID: dUE3V3ZUOWZoeWRjb3p5ejVhbG8=
AWS_SECRET_ACCESS_KEY: QXVzRXk2S0txYW5RUVUzWnczclhZQmFpUzVCTThhUG9BS2ZwY2JGcg==
EMAIL_USER: dmFpYmhhdi5zYWhhc3JhcmFAZ21haWwuY29t
EMAIL_PASS: cGV6amN4Zm5lZ2d1emt1aA==
PAYTM_MERCHANT_ID: eW91cl9tZXJjaGFudF9pZA==
PAYTM_MERCHANT_KEY: YWJjZDEyMzRhYmNkMTIzNA==
WAPP_TOKEN: Y2x6Z2t0emRiYXdzNW1nZHU3c3M1YTRyYQ==

13
k8s/backend/service.yaml Normal file
View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: ecommerce
spec:
type: NodePort
selector:
app: backend
ports:
- port: 3000
targetPort: 3000
nodePort: 30080

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: database

View File

@@ -0,0 +1,218 @@
# Database Namespace — Setup & On-Premise Replication Guide
Covers PostgreSQL 16 and MongoDB 7 deployed in the `database` Kubernetes namespace.
Verified working on: **minikube** (local dev). On-premise steps are in [Section 4](#4-on-premise-replication).
---
## 1. What's Deployed
| Resource | Namespace | Details |
|---|---|---|
| StatefulSet `postgres` | `database` | `postgres:16`, 1 replica, 5 Gi PVC |
| StatefulSet `mongodb` | `database` | `mongo:7`, 1 replica, 5 Gi PVC, no auth |
| Service `postgres` | `database` | ClusterIP, port 5432 |
| Service `mongodb` | `database` | ClusterIP, port 27017 |
| Secret `postgres-secret` | `database` | DB name, user, password, DATABASE_URL |
| PVC `postgres-pvc` | `database` | 5 Gi, ReadWriteOnce |
| PVC `mongodb-pvc` | `database` | 5 Gi, ReadWriteOnce |
| ConfigMap `tcp-services` | `ingress-nginx` | TCP passthrough for external PostgreSQL access |
---
## 2. Connection Strings
| Consumer | URL |
|---|---|
| Backend pod (in-cluster) | `postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public` |
| Backend pod (in-cluster) | `mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products` |
| External / pgAdmin (host) | `postgresql://vaishnavi:admin@postgres.local:5432/vaishnavi_db` |
---
## 3. File Structure
```
k8s/database/
├── 00-namespace.yaml # database namespace
├── postgres-secret.yaml # base64-encoded credentials + DATABASE_URL
├── postgres-pvc.yaml # 5 Gi PVC
├── postgres-statefulset.yaml # postgres:16 StatefulSet
├── postgres-service.yaml # ClusterIP :5432
├── mongodb-pvc.yaml # 5 Gi PVC
├── mongodb-statefulset.yaml # mongo:7 StatefulSet, no auth
├── mongodb-service.yaml # ClusterIP :27017
└── nginx-tcp-configmap.yaml # TCP passthrough for postgres.local:5432
```
---
## 4. On-Premise Replication
### 4.1 Prerequisites
- Kubernetes cluster (kubeadm, k3s, RKE2, or similar) with at least 1 worker node
- `kubectl` configured with cluster-admin rights
- A StorageClass that supports `ReadWriteOnce` PVCs
Common options:
- `local-path` (Rancher Local Path Provisioner — simplest for single-node)
- `longhorn` (multi-node HA storage)
- NFS provisioner
- Ingress-NGINX controller deployed (`kubectl get pods -n ingress-nginx`)
---
### 4.2 StorageClass: Install Local Path Provisioner (if needed)
```bash
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
# Set as default if no other default exists
kubectl patch storageclass local-path \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
```
---
### 4.3 Deploy the Databases
```bash
cd vaishnavi-ecommerce-backend/k8s/database
kubectl apply -f 00-namespace.yaml
kubectl apply -f postgres-secret.yaml
kubectl apply -f postgres-pvc.yaml
kubectl apply -f postgres-statefulset.yaml
kubectl apply -f postgres-service.yaml
kubectl apply -f mongodb-pvc.yaml
kubectl apply -f mongodb-statefulset.yaml
kubectl apply -f mongodb-service.yaml
```
Wait for both pods to reach `Running`:
```bash
kubectl get pods -n database -w
# Expected:
# mongodb-0 1/1 Running 0
# postgres-0 1/1 Running 0
```
---
### 4.4 External PostgreSQL Access via TCP Ingress (optional)
This lets you connect to PostgreSQL from outside the cluster using `postgres.local:5432`.
**Step 1 — Apply the TCP ConfigMap:**
```bash
kubectl apply -f nginx-tcp-configmap.yaml
```
**Step 2 — Expose port 5432 on the ingress-nginx Service:**
```bash
kubectl patch svc ingress-nginx-controller -n ingress-nginx \
--type='json' \
-p='[{"op":"add","path":"/spec/ports/-","value":{"name":"postgres","port":5432,"targetPort":5432,"protocol":"TCP"}}]'
```
**Step 3 — Add `--tcp-services-configmap` arg to the ingress-nginx Deployment:**
```bash
kubectl patch deployment ingress-nginx-controller -n ingress-nginx \
--type='json' \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--tcp-services-configmap=ingress-nginx/tcp-services"}]'
```
**Step 4 — Add to `/etc/hosts` on every machine that needs external access:**
```
<NODE_IP> postgres.local
```
Replace `<NODE_IP>` with the IP of any cluster node (or load balancer IP if using MetalLB).
---
### 4.5 Credentials / Secret Values
The secret values are baked into `postgres-secret.yaml`. To change them:
```bash
# Generate new base64 values
echo -n "your_password" | base64
# Or use kubectl to create the secret directly (bypasses base64 manual encoding)
kubectl create secret generic postgres-secret \
--namespace=database \
--from-literal=POSTGRES_DB=vaishnavi_db \
--from-literal=POSTGRES_USER=vaishnavi \
--from-literal=POSTGRES_PASSWORD=admin \
--from-literal=DATABASE_URL="postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public" \
--dry-run=client -o yaml > postgres-secret.yaml
```
---
### 4.6 Backend ConfigMap / Secret Reference
The backend reads DATABASE_URL and MONGODB_URI from its own configmap/secret in the `ecommerce` namespace. Ensure these point to the `database` namespace services:
```yaml
DATABASE_URL: postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public
MONGODB_URI: mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products
```
---
## 5. Verification
```bash
# Both pods Running
kubectl get pods -n database
# PVCs Bound
kubectl get pvc -n database
# Services present
kubectl get svc -n database
# PostgreSQL accepting connections
kubectl exec -n database postgres-0 -- pg_isready -U vaishnavi -d vaishnavi_db
# PostgreSQL — list databases
kubectl exec -n database postgres-0 -- psql -U vaishnavi -d vaishnavi_db -c '\l'
# MongoDB ping
kubectl exec -n database mongodb-0 -- mongosh --eval "db.adminCommand('ping')" --quiet
# In-cluster connectivity test (PostgreSQL)
kubectl run psql-test --rm -it --image=postgres:16 --restart=Never -n database -- \
psql postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db -c '\l'
# In-cluster connectivity test (MongoDB)
kubectl run mongo-test --rm -it --image=mongo:7 --restart=Never -n database -- \
mongosh mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products --eval "db.stats()"
# External PostgreSQL (after TCP ingress setup + /etc/hosts)
psql postgresql://vaishnavi:admin@postgres.local:5432/vaishnavi_db -c '\l'
```
---
## 6. Teardown
```bash
# Remove databases (data is lost when PVCs are deleted)
kubectl delete namespace database
# Remove TCP ingress config (if applied)
kubectl delete configmap tcp-services -n ingress-nginx
```
To preserve data before teardown, dump first:
```bash
# PostgreSQL dump
kubectl exec -n database postgres-0 -- \
pg_dump -U vaishnavi vaishnavi_db > vaishnavi_db_backup.sql
# MongoDB dump
kubectl exec -n database mongodb-0 -- \
mongodump --db vaishnavi_products --archive > vaishnavi_products_backup.archive
```

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc
namespace: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: mongodb
namespace: database
spec:
type: ClusterIP
selector:
app: mongodb
ports:
- name: mongodb
port: 27017
targetPort: 27017

View File

@@ -0,0 +1,45 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: database
spec:
serviceName: mongodb
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:7
ports:
- containerPort: 27017
volumeMounts:
- name: mongodb-data
mountPath: /data/db
livenessProbe:
exec:
command:
- mongosh
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 6
readinessProbe:
exec:
command:
- mongosh
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
"5432": "database/postgres:5432"
# ─── Manual one-time steps after applying this ConfigMap ─────────────────────
#
# 1. Expose port 5432 on the ingress-nginx-controller Service:
#
# kubectl patch svc ingress-nginx-controller -n ingress-nginx \
# --type='json' \
# -p='[{"op":"add","path":"/spec/ports/-","value":{"name":"postgres","port":5432,"targetPort":5432,"protocol":"TCP"}}]'
#
# 2. Add --tcp-services-configmap arg to the ingress-nginx-controller Deployment:
#
# kubectl patch deployment ingress-nginx-controller -n ingress-nginx \
# --type='json' \
# -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--tcp-services-configmap=ingress-nginx/tcp-services"}]'
#
# 3. Add to /etc/hosts on your host machine:
#
# 192.168.49.2 postgres.local
#
# ─────────────────────────────────────────────────────────────────────────────

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
namespace: database
type: Opaque
data:
POSTGRES_DB: dmFpc2huYXZpX2Ri # vaishnavi_db
POSTGRES_USER: dmFpc2huYXZp # vaishnavi
POSTGRES_PASSWORD: YWRtaW4= # admin
DATABASE_URL: cG9zdGdyZXNxbDovL3ZhaXNobmF2aTphZG1pbkBwb3N0Z3Jlcy5kYXRhYmFzZS5zdmMuY2x1c3Rlci5sb2NhbDo1NDMyL3ZhaXNobmF2aV9kYj9zY2hlbWE9cHVibGlj

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: database
spec:
type: ClusterIP
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: 5432

View File

@@ -0,0 +1,67 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: database
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_DB
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_PASSWORD
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
livenessProbe:
exec:
command:
- pg_isready
- -U
- $(POSTGRES_USER)
- -d
- $(POSTGRES_DB)
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 6
readinessProbe:
exec:
command:
- pg_isready
- -U
- $(POSTGRES_USER)
- -d
- $(POSTGRES_DB)
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgres-pvc

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: database
spec:
type: ClusterIP
selector:
app: redis
ports:
- port: 6379
targetPort: 6379

View File

@@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: database
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
command:
- redis-server
- --appendonly
- "yes"
ports:
- containerPort: 6379
volumeMounts:
- name: redis-data
mountPath: /data
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 6
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc