feat: complete MongoDB to CouchDB migration

- Migrate Report model to CouchDB with embedded street/user data
- Migrate UserBadge model to CouchDB with badge population
- Update all remaining routes (reports, users, badges, payments) to use CouchDB
- Add CouchDB health check and graceful shutdown to server.js
- Add missing methods to couchdbService (checkConnection, findWithPagination, etc.)
- Update Kubernetes deployment manifests for CouchDB support
- Add comprehensive CouchDB setup documentation

All core functionality now uses CouchDB as primary database while maintaining
MongoDB for backward compatibility during transition period.

🤖 Generated with [AI Assistant]

Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
This commit is contained in:
William Valentin
2025-11-01 13:29:48 -07:00
parent 9ac21fca72
commit df94c17e1f
14 changed files with 684 additions and 155 deletions

View File

@@ -10,7 +10,8 @@ deploy/
│ ├── namespace.yaml # Namespace definition
│ ├── configmap.yaml # Environment configuration
│ ├── secrets.yaml.example # Secret template (COPY TO secrets.yaml)
│ ├── mongodb-statefulset.yaml # MongoDB StatefulSet with PVC
│ ├── couchdb-statefulset.yaml # CouchDB StatefulSet with PVC
│ ├── couchdb-configmap.yaml # CouchDB configuration
│ ├── backend-deployment.yaml # Backend Deployment + Service
│ ├── frontend-deployment.yaml # Frontend Deployment + Service
│ └── ingress.yaml # Ingress for routing
@@ -94,6 +95,19 @@ nano deploy/k8s/frontend-deployment.yaml
# Change: image: your-registry/adopt-a-street-frontend:latest
```
### 4. Configure CouchDB
```bash
# Apply CouchDB configuration
kubectl apply -f deploy/k8s/couchdb-configmap.yaml
# Deploy CouchDB
kubectl apply -f deploy/k8s/couchdb-statefulset.yaml
# Wait for CouchDB to be ready
kubectl wait --for=condition=ready pod -l app=couchdb -n adopt-a-street --timeout=120s
```
### 4. Update Domain Name
Update the ingress host:
@@ -116,11 +130,9 @@ kubectl apply -f deploy/k8s/secrets.yaml
# Create ConfigMap
kubectl apply -f deploy/k8s/configmap.yaml
# Deploy MongoDB
kubectl apply -f deploy/k8s/mongodb-statefulset.yaml
# Wait for MongoDB to be ready (this may take 1-2 minutes)
kubectl wait --for=condition=ready pod -l app=mongodb -n adopt-a-street --timeout=120s
# Deploy CouchDB (already done in step 4)
# Wait for CouchDB to be ready (this may take 1-2 minutes)
kubectl wait --for=condition=ready pod -l app=couchdb -n adopt-a-street --timeout=120s
# Deploy backend
kubectl apply -f deploy/k8s/backend-deployment.yaml
@@ -155,7 +167,7 @@ kubectl get pods -n adopt-a-street
# adopt-a-street-backend-xxxxxxxxxx-xxxxx 1/1 Running 0 5m
# adopt-a-street-frontend-xxxxxxxxx-xxxxx 1/1 Running 0 5m
# adopt-a-street-frontend-xxxxxxxxx-xxxxx 1/1 Running 0 5m
# adopt-a-street-mongodb-0 1/1 Running 0 10m
# adopt-a-street-couchdb-0 1/1 Running 0 10m
```
### Check Logs
@@ -167,8 +179,8 @@ kubectl logs -f deployment/adopt-a-street-backend -n adopt-a-street
# Frontend logs
kubectl logs -f deployment/adopt-a-street-frontend -n adopt-a-street
# MongoDB logs
kubectl logs -f adopt-a-street-mongodb-0 -n adopt-a-street
# CouchDB logs
kubectl logs -f adopt-a-street-couchdb-0 -n adopt-a-street
```
### Check Services
@@ -180,7 +192,7 @@ kubectl get svc -n adopt-a-street
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# adopt-a-street-backend ClusterIP 10.43.x.x <none> 5000/TCP 5m
# adopt-a-street-frontend ClusterIP 10.43.x.x <none> 80/TCP 5m
# adopt-a-street-mongodb ClusterIP None <none> 27017/TCP 10m
# adopt-a-street-couchdb ClusterIP None <none> 5984/TCP 10m
```
### Check Ingress
@@ -205,10 +217,11 @@ kubectl port-forward svc/adopt-a-street-frontend 3000:80 -n adopt-a-street
The deployment is optimized for Raspberry Pi hardware:
### MongoDB (Pi 5 nodes only)
### CouchDB (Pi 5 nodes only)
- **Requests:** 512Mi RAM, 250m CPU
- **Limits:** 2Gi RAM, 1000m CPU
- **Storage:** 10Gi persistent volume
- **Additional:** 64Mi RAM, 50m CPU for metrics exporter
### Backend (prefers Pi 5 nodes)
- **Requests:** 256Mi RAM, 100m CPU
@@ -221,7 +234,7 @@ The deployment is optimized for Raspberry Pi hardware:
- **Replicas:** 2 pods
### Total Cluster Requirements
- **Minimum RAM:** ~3.5 GB (1.5GB MongoDB + 1GB backend + 200MB frontend + 800MB system)
- **Minimum RAM:** ~3.6 GB (1.5GB CouchDB + 1GB backend + 200MB frontend + 800MB system)
- **Recommended:** 2x Pi 5 (8GB each) handles this comfortably
## Scaling
@@ -236,7 +249,7 @@ kubectl scale deployment adopt-a-street-backend --replicas=3 -n adopt-a-street
kubectl scale deployment adopt-a-street-frontend --replicas=3 -n adopt-a-street
```
**Note:** MongoDB is a StatefulSet with 1 replica. Scaling MongoDB requires configuring replication.
**Note:** CouchDB is a StatefulSet with 1 replica. Scaling CouchDB requires configuring clustering.
## Updating
@@ -318,14 +331,17 @@ kubectl logs <pod-name> -n adopt-a-street --previous
- Verify cluster can access registry
- Check if imagePullSecrets are needed
### MongoDB Connection Issues
### CouchDB Connection Issues
```bash
# Shell into backend pod
kubectl exec -it <backend-pod-name> -n adopt-a-street -- sh
# Test MongoDB connection
wget -qO- http://adopt-a-street-mongodb:27017
# Test CouchDB connection
curl -f http://adopt-a-street-couchdb:5984/_up
# Test authentication
curl -u $COUCHDB_USER:$COUCHDB_PASSWORD http://adopt-a-street-couchdb:5984/_session
```
### Persistent Volume Issues
@@ -353,7 +369,8 @@ kubectl delete namespace adopt-a-street
kubectl delete -f deploy/k8s/ingress.yaml
kubectl delete -f deploy/k8s/frontend-deployment.yaml
kubectl delete -f deploy/k8s/backend-deployment.yaml
kubectl delete -f deploy/k8s/mongodb-statefulset.yaml
kubectl delete -f deploy/k8s/couchdb-statefulset.yaml
kubectl delete -f deploy/k8s/couchdb-configmap.yaml
kubectl delete -f deploy/k8s/configmap.yaml
kubectl delete -f deploy/k8s/secrets.yaml
kubectl delete -f deploy/k8s/namespace.yaml
@@ -365,20 +382,21 @@ kubectl delete -f deploy/k8s/namespace.yaml
1. **Never commit secrets.yaml** - Always use secrets.yaml.example
2. **Use strong JWT_SECRET** - Generate with: `openssl rand -base64 32`
3. **Enable TLS/HTTPS** - Uncomment TLS section in ingress.yaml and use cert-manager
4. **Restrict ingress** - Use network policies to limit pod communication
5. **Use image digests** - Pin images to specific SHA256 digests for production
6. **Enable RBAC** - Create service accounts with minimal permissions
7. **Scan images** - Use tools like Trivy to scan for vulnerabilities
3. **Use strong CouchDB passwords** - Generate with: `openssl rand -base64 32`
4. **Enable TLS/HTTPS** - Uncomment TLS section in ingress.yaml and use cert-manager
5. **Restrict ingress** - Use network policies to limit pod communication
6. **Use image digests** - Pin images to specific SHA256 digests for production
7. **Enable RBAC** - Create service accounts with minimal permissions
8. **Scan images** - Use tools like Trivy to scan for vulnerabilities
## Performance Optimization
1. **Use imagePullPolicy: IfNotPresent** - After initial deployment to save bandwidth
2. **Implement HPA** - Horizontal Pod Autoscaler for dynamic scaling
3. **Add Redis** - For caching to reduce MongoDB load
3. **Add Redis** - For caching to reduce CouchDB load
4. **Use CDN** - For frontend static assets
5. **Enable compression** - Nginx already configured with gzip
6. **Monitor resources** - Use Prometheus + Grafana for metrics
6. **Monitor resources** - Use Prometheus + Grafana for metrics (CouchDB exporter included)
## Additional Resources