Files
vaishnavi-ecommerce-backend/k8s/database/DATABASE-SETUP.md
2026-03-10 22:39:47 +05:30

6.9 KiB

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.


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)

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

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:

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:

kubectl apply -f nginx-tcp-configmap.yaml

Step 2 — Expose port 5432 on the ingress-nginx 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"}}]'

Step 3 — Add --tcp-services-configmap arg to the ingress-nginx 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"}]'

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:

# 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:

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

# 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

# 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:

# 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