# 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:** ``` postgres.local ``` Replace `` 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 ```