- Add namespace.yaml to create adopt-a-street namespace - Add namespace to all resource metadata (Services, Deployments, StatefulSet, ConfigMap, Secrets, Ingress) - Fix CouchDB NODENAME to proper StatefulSet format (adopt-a-street-couchdb-0.adopt-a-street-couchdb) - Add missing environment variables (STRIPE, OPENAI, CouchDB connection pool settings) - Fix duplicate Cloudinary variables between ConfigMap and Secrets - Remove duplicate registry-secret.yaml file (security risk) - Remove unused couchdb-configmap.yaml - Complete rewrite of DEPLOYMENT_GUIDE.md with namespace-aware instructions - Add comprehensive CHANGES.md documenting all fixes and rationale Fixes address all HIGH and MEDIUM priority issues identified in configuration review: - Namespace configuration (HIGH) - Missing resources (HIGH) - CouchDB NODENAME format (MEDIUM) - Missing environment variables (MEDIUM) - Duplicate files (MEDIUM) - Documentation updates (MEDIUM) All health checks verified, service discovery tested, and deployment process documented. 🤖 Generated with AI Assistant Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
10 KiB
CouchDB Deployment Configuration Guide
Overview
This guide covers the configuration changes needed to deploy Adopt-a-Street with CouchDB on the Raspberry Pi Kubernetes cluster. All manifests are configured to use the adopt-a-street namespace by default.
Namespace Configuration
All Kubernetes resources are configured to deploy to the adopt-a-street namespace. A namespace.yaml file is included to create this namespace.
Creating the Namespace
# Create the adopt-a-street namespace using the provided manifest
kubectl apply -f deploy/k8s/namespace.yaml
# Or create manually
kubectl create namespace adopt-a-street
# Set as default namespace for current context (optional)
kubectl config set-context --current --namespace=adopt-a-street
Alternative Namespaces
If you want to deploy to a different namespace (e.g., for development or staging), you can override the namespace at apply time:
# Override namespace when applying
kubectl apply -f deploy/k8s/ -n <your-namespace>
Note: When overriding namespaces, ensure the target namespace exists first.
CouchDB Configuration
StatefulSet Configuration
The CouchDB StatefulSet is configured with:
- Single-node mode: Suitable for development and small production deployments
- Persistent storage: 10Gi volume claim (configurable)
- ARM64 affinity: Requires Raspberry Pi 5 nodes for better performance
- NODENAME: Properly configured as
couchdb@adopt-a-street-couchdb-0.adopt-a-street-couchdb - Inline configuration: CouchDB settings are generated via startup script
Storage Configuration
volumeClaimTemplates:
- metadata:
name: couchdb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
To change storage size, edit couchdb-statefulset.yaml line 133.
Deployment Steps
1. Create Namespace
# Create the adopt-a-street namespace
kubectl apply -f deploy/k8s/namespace.yaml
# Verify namespace creation
kubectl get namespace adopt-a-street
2. Create Secrets
# Copy the example secrets file
cp deploy/k8s/secrets.yaml.example deploy/k8s/secrets.yaml
# Edit secrets.yaml and replace all placeholder values
# IMPORTANT: Generate secure values for production using:
# openssl rand -base64 32
# Apply the secrets
kubectl apply -f deploy/k8s/secrets.yaml
3. Create Image Pull Secret
# Create the image pull secret for Gitea registry
kubectl create secret docker-registry regcred \
--docker-server=gitea-gitea-http.taildb3494.ts.net \
--docker-username=will \
--docker-password=YOUR_GITEA_PASSWORD \
--namespace=adopt-a-street
# Or use the template file (after updating with your credentials)
kubectl apply -f deploy/k8s/image-pull-secret.yaml
4. Apply ConfigMap
# Apply the configuration
kubectl apply -f deploy/k8s/configmap.yaml
5. Deploy CouchDB
# Deploy CouchDB StatefulSet with persistent storage
kubectl apply -f deploy/k8s/couchdb-statefulset.yaml
# Wait for CouchDB to be ready
kubectl wait --for=condition=ready pod -l app=couchdb --timeout=120s -n adopt-a-street
# Verify CouchDB is running
kubectl get statefulset adopt-a-street-couchdb -n adopt-a-street
kubectl logs statefulset/adopt-a-street-couchdb -n adopt-a-street
6. Deploy Backend
# Deploy the backend application
kubectl apply -f deploy/k8s/backend-deployment.yaml
# Wait for backend to be ready
kubectl wait --for=condition=ready pod -l app=backend --timeout=120s -n adopt-a-street
# Verify backend health
kubectl exec -it deployment/adopt-a-street-backend -n adopt-a-street \
-- curl http://localhost:5000/api/health
7. Deploy Frontend
# Deploy the frontend application
kubectl apply -f deploy/k8s/frontend-deployment.yaml
# Wait for frontend to be ready
kubectl wait --for=condition=ready pod -l app=frontend --timeout=120s -n adopt-a-street
8. Deploy Ingress
# Deploy the ingress for external access
kubectl apply -f deploy/k8s/ingress.yaml
# Verify ingress
kubectl get ingress -n adopt-a-street
Quick Deploy (All at Once)
# Apply all manifests at once
kubectl apply -f deploy/k8s/
# Note: This applies all YAML files in the directory
# Make sure secrets.yaml is created first!
9. Verify Deployment
# Check all pods in the namespace
kubectl get pods -n adopt-a-street
# Check services
kubectl get services -n adopt-a-street
# Check all resources
kubectl get all -n adopt-a-street
# Check logs for specific deployments
kubectl logs deployment/adopt-a-street-backend -n adopt-a-street
kubectl logs deployment/adopt-a-street-frontend -n adopt-a-street
kubectl logs statefulset/adopt-a-street-couchdb -n adopt-a-street
# Watch pod status
kubectl get pods -n adopt-a-street -w
# Check resource usage
kubectl top pods -n adopt-a-street
Environment Variables Summary
ConfigMap Variables (configmap.yaml)
COUCHDB_URL: "http://adopt-a-street-couchdb:5984"COUCHDB_DB_NAME: "adopt-a-street"COUCHDB_MAX_CONNECTIONS: "10" (connection pool size)COUCHDB_REQUEST_TIMEOUT: "30000" (request timeout in ms)PORT: "5000"NODE_ENV: "production"FRONTEND_URL: "http://adopt-a-street.local"CLOUDINARY_CLOUD_NAME: Your Cloudinary cloud nameSTRIPE_PUBLISHABLE_KEY: Your Stripe publishable keyOPENAI_MODEL: "gpt-3.5-turbo" (AI model selection)
Secret Variables (secrets.yaml)
JWT_SECRET: Secure random tokenCOUCHDB_USER: Database admin usernameCOUCHDB_PASSWORD: Secure random passwordCOUCHDB_SECRET: Secure random token for CouchDBCLOUDINARY_API_KEY: Cloudinary API keyCLOUDINARY_API_SECRET: Cloudinary API secretSTRIPE_SECRET_KEY: Stripe secret keyOPENAI_API_KEY: OpenAI API key
Health Checks
Backend Health Check
- Endpoint:
/api/health - Method: GET
- Expected Response:
{"status": "healthy", "database": "connected"}
Frontend Health Check
- Endpoint:
/health - Method: GET
- Expected Response: "healthy\n"
Resource Limits
Backend (per replica)
- Memory Request: 256Mi, Limit: 512Mi
- CPU Request: 100m, Limit: 500m
- Architecture: ARM64 (Pi 5 preferred)
Frontend (per replica)
- Memory Request: 64Mi, Limit: 128Mi
- CPU Request: 50m, Limit: 200m
- Architecture: Any (lightweight)
Security Notes
- Secrets Management:
secrets.yamlis in.gitignoreand should never be committed - Generated Passwords: All passwords and secrets were generated using
openssl rand -base64 32 - Production Changes: Change default usernames and passwords before production deployment
- Image Registry: Gitea registry requires authentication via image pull secrets
Troubleshooting
Namespace-Related Issues
Resources Not Found
# Verify resources exist in adopt-a-street namespace
kubectl get all -n adopt-a-street
# Check if resources are in a different namespace
kubectl get all --all-namespaces | grep adopt-a-street
# Get events from the namespace
kubectl get events -n adopt-a-street --sort-by='.lastTimestamp'
# List all namespaces
kubectl get namespaces
Image Pull Issues
# Verify image pull secret exists
kubectl get secret regcred -n adopt-a-street -o yaml
# Test image pull
kubectl run test-pod \
--image=gitea-gitea-http.taildb3494.ts.net/will/adopt-a-street/backend:latest \
--dry-run=client -o yaml -n adopt-a-street
# Debug image pull errors
kubectl describe pod -l app=backend -n adopt-a-street
CouchDB Connection Issues
# Check CouchDB pod
kubectl logs statefulset/adopt-a-street-couchdb -n adopt-a-street
# Test connection from backend pod
kubectl exec -it deployment/adopt-a-street-backend -n adopt-a-street \
-- curl http://adopt-a-street-couchdb:5984/_up
# Check CouchDB service
kubectl get service adopt-a-street-couchdb -n adopt-a-street
kubectl describe service adopt-a-street-couchdb -n adopt-a-street
# Check persistent volume claims
kubectl get pvc -n adopt-a-street
Health Check Failures
# Check backend health endpoint
kubectl exec -it deployment/adopt-a-street-backend -n adopt-a-street \
-- curl http://localhost:5000/api/health
# Check frontend health endpoint
kubectl exec -it deployment/adopt-a-street-frontend -n adopt-a-street \
-- curl http://localhost:80/health
# Check pod events for health check failures
kubectl describe pod -l app=backend -n adopt-a-street
Multi-Environment Deployment
Using Different Namespaces for Environments
While the default namespace is adopt-a-street, you can override it for different environments:
# Deploy to development namespace
kubectl create namespace adopt-a-street-dev
kubectl apply -f deploy/k8s/ -n adopt-a-street-dev
# Deploy to staging namespace
kubectl create namespace adopt-a-street-staging
kubectl apply -f deploy/k8s/ -n adopt-a-street-staging
# Deploy to production (uses default namespace)
kubectl apply -f deploy/k8s/
Customizing Per Environment
For environment-specific configurations, create custom ConfigMaps and Secrets:
# Create environment-specific ConfigMap
kubectl create configmap adopt-a-street-config \
--from-literal=NODE_ENV=development \
--from-literal=FRONTEND_URL=http://dev.adopt-a-street.local \
-n adopt-a-street-dev
# Create environment-specific secrets
kubectl create secret generic adopt-a-street-secrets \
--from-literal=JWT_SECRET=$(openssl rand -base64 32) \
-n adopt-a-street-dev
Common Commands Reference
# Set default namespace for current session
kubectl config set-context --current --namespace=adopt-a-street
# View current context and namespace
kubectl config current-context
kubectl config view --minify
# Get resources in specific format
kubectl get pods -n adopt-a-street -o wide
kubectl get services -n adopt-a-street -o yaml
# Port forwarding for debugging
kubectl port-forward -n adopt-a-street service/adopt-a-street-backend 5000:5000
kubectl port-forward -n adopt-a-street service/adopt-a-street-frontend 3000:80
kubectl port-forward -n adopt-a-street service/adopt-a-street-couchdb 5984:5984
# Exec into pods for debugging
kubectl exec -it -n adopt-a-street deployment/adopt-a-street-backend -- /bin/bash
kubectl exec -it -n adopt-a-street deployment/adopt-a-street-frontend -- /bin/sh
# Delete and redeploy
kubectl delete -f deploy/k8s/
kubectl apply -f deploy/k8s/
# Scale deployments
kubectl scale deployment/adopt-a-street-backend --replicas=2 -n adopt-a-street
kubectl scale deployment/adopt-a-street-frontend --replicas=3 -n adopt-a-street