React + Node.js/Express app deployed as a Kubernetes pod, connected to Aurora MySQL with separate Writer and Reader endpoints.
Browser ──► K8s Service ──► Pod (React SPA + Express API)
│
┌───────────────┴────────────────┐
│ writerPool │ readerPool
▼ ▼
Aurora Writer Endpoint Aurora Reader Endpoint
(INSERT / UPDATE / DELETE) (SELECT / COUNT)
mysql -h <WRITER_HOST> -u admin -p < schema.sql# Edit your endpoints and credentials
vim k8s/configmap.yaml # DB_WRITER_HOST, DB_READER_HOST, DB_NAME
vim k8s/secret.yaml # DB_USER, DB_PASSWORD
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yamldocker build -t your-registry/nexus-crm:latest .
docker push your-registry/nexus-crm:latest
# Update image name in k8s/deployment.yamlkubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl get pods -l app=nexus-crmkubectl port-forward svc/nexus-crm-svc 8080:80
curl http://localhost:8080/readyz
# {"status":"ready","writer":"ok","reader":"ok"}# Backend
cd backend && npm install
DB_WRITER_HOST=localhost DB_READER_HOST=localhost \
DB_USER=root DB_PASSWORD=pass DB_NAME=crm_db \
npm run dev
# Frontend (separate terminal)
cd frontend && npm install && npm run dev
# → http://localhost:5173 (proxies /api to :3001)| Method | Path | DB Pool | Description |
|---|---|---|---|
| GET | /api/contacts | Reader | List + search + filter |
| GET | /api/contacts/stats | Reader | Counts by status |
| GET | /api/contacts/:id | Reader | Single contact |
| POST | /api/contacts | Writer | Create contact |
| PUT | /api/contacts/:id | Writer | Update contact |
| DELETE | /api/contacts/:id | Writer | Delete contact |
| GET | /healthz | — | Liveness probe |
| GET | /readyz | Both | Readiness probe |
- Pod anti-affinity spreads replicas across AZs (matches Aurora multi-zone)
- Readiness probe hits
/readyzwhich pings both writer & reader before accepting traffic - HPA scales 2→8 pods at 65% CPU
- Rolling update with
maxUnavailable: 0= zero downtime deploys