Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution - Reorganized documentation structure - Set up Husky + lint-staged for efficient pre-commit hooks - Fixed Dockerfile healthcheck issue - Added comprehensive documentation index
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
# Kubernetes Manifests for RxMinder
|
||||
|
||||
This directory contains Kubernetes manifests and templates for deploying RxMinder on a Kubernetes cluster.
|
||||
|
||||
## 🎯 Template-Based Deployment (Recommended)
|
||||
|
||||
RxMinder uses **template files** with environment variable substitution for secure, user-friendly deployment.
|
||||
|
||||
### **Template Files**
|
||||
|
||||
- `couchdb-secret.yaml.template` - Database credentials (uses `stringData` - no base64 encoding needed!)
|
||||
- `ingress.yaml.template` - Ingress configuration with customizable hostname
|
||||
- `configmap.yaml.template` - Application configuration
|
||||
- `frontend-deployment.yaml.template` - Frontend deployment
|
||||
|
||||
### **Static Files**
|
||||
|
||||
- `couchdb-statefulset.yaml` - StatefulSet for CouchDB database
|
||||
- `couchdb-service.yaml` - Service to expose CouchDB
|
||||
- `couchdb-pvc.yaml` - PersistentVolumeClaim for CouchDB storage
|
||||
- `db-seed-job.yaml` - Job to seed initial database data
|
||||
- `frontend-service.yaml` - Service to expose frontend
|
||||
- `hpa.yaml` - Horizontal Pod Autoscaler
|
||||
- `network-policy.yaml` - Network security policies
|
||||
|
||||
## 🚀 Deployment Instructions
|
||||
|
||||
### **Option 1: Template-Based Deployment (Recommended)**
|
||||
|
||||
```bash
|
||||
# 1. Copy and configure environment
|
||||
cp .env.example .env
|
||||
|
||||
# 2. Edit .env with your settings
|
||||
nano .env
|
||||
# Set: APP_NAME, COUCHDB_PASSWORD, INGRESS_HOST, etc.
|
||||
|
||||
# 3. Deploy with templates
|
||||
./scripts/k8s-deploy-template.sh deploy
|
||||
|
||||
# 4. Check status
|
||||
./scripts/k8s-deploy-template.sh status
|
||||
|
||||
# 5. Cleanup (if needed)
|
||||
./scripts/k8s-deploy-template.sh delete
|
||||
```
|
||||
|
||||
**Benefits of template approach:**
|
||||
|
||||
- ✅ No manual base64 encoding required
|
||||
- ✅ Secure credential management via `.env`
|
||||
- ✅ Automatic dependency ordering
|
||||
- ✅ Built-in validation and status checking
|
||||
- ✅ Easy customization of app name and configuration
|
||||
|
||||
### **Option 2: Manual Deployment**
|
||||
|
||||
For advanced users who want manual control:
|
||||
|
||||
```bash
|
||||
# Manual template processing (requires envsubst)
|
||||
envsubst < couchdb-secret.yaml.template > /tmp/couchdb-secret.yaml
|
||||
envsubst < ingress.yaml.template > /tmp/ingress.yaml
|
||||
|
||||
# Apply resources in order
|
||||
kubectl apply -f /tmp/couchdb-secret.yaml
|
||||
kubectl apply -f couchdb-pvc.yaml
|
||||
kubectl apply -f couchdb-service.yaml
|
||||
kubectl apply -f couchdb-statefulset.yaml
|
||||
kubectl apply -f configmap.yaml.template
|
||||
kubectl apply -f frontend-deployment.yaml.template
|
||||
kubectl apply -f frontend-service.yaml
|
||||
kubectl apply -f /tmp/ingress.yaml
|
||||
kubectl apply -f network-policy.yaml
|
||||
kubectl apply -f hpa.yaml
|
||||
kubectl apply -f db-seed-job.yaml
|
||||
```
|
||||
|
||||
### **Environment Configuration**
|
||||
|
||||
Create `.env` with these required variables:
|
||||
|
||||
```bash
|
||||
# Application Configuration
|
||||
APP_NAME=rxminder # Customize your app name
|
||||
INGRESS_HOST=rxminder.yourdomain.com # Your external hostname
|
||||
|
||||
# Docker Image Configuration
|
||||
DOCKER_IMAGE=myregistry.com/rxminder:v1.0.0 # Your container image
|
||||
|
||||
# Database Credentials
|
||||
COUCHDB_USER=admin
|
||||
COUCHDB_PASSWORD=super-secure-password-123
|
||||
|
||||
# Storage Configuration
|
||||
STORAGE_CLASS=longhorn # Your cluster's storage class
|
||||
STORAGE_SIZE=20Gi # Database storage allocation
|
||||
|
||||
# Optional: Advanced Configuration
|
||||
VITE_COUCHDB_URL=http://localhost:5984
|
||||
APP_BASE_URL=https://rxminder.yourdomain.com
|
||||
```
|
||||
|
||||
### **Docker Image Options**
|
||||
|
||||
Configure the container image based on your registry:
|
||||
|
||||
| Registry Type | Example Image | Use Case |
|
||||
| ----------------------------- | -------------------------------------------------------------- | ------------------ |
|
||||
| **Docker Hub** | `rxminder/rxminder:v1.0.0` | Public releases |
|
||||
| **GitHub Container Registry** | `ghcr.io/username/rxminder:latest` | GitHub integration |
|
||||
| **AWS ECR** | `123456789012.dkr.ecr.us-west-2.amazonaws.com/rxminder:v1.0.0` | AWS deployments |
|
||||
| **Google GCR** | `gcr.io/project-id/rxminder:stable` | Google Cloud |
|
||||
| **Private Registry** | `registry.company.com/rxminder:production` | Enterprise |
|
||||
| **Local Registry** | `localhost:5000/rxminder:dev` | Development |
|
||||
|
||||
### **Storage Class Options**
|
||||
|
||||
Choose the appropriate storage class for your environment:
|
||||
|
||||
| Platform | Recommended Storage Class | Notes |
|
||||
| --------------------------- | ------------------------- | -------------------------------- |
|
||||
| **Raspberry Pi + Longhorn** | `longhorn` | Distributed storage across nodes |
|
||||
| **k3s** | `local-path` | Single-node local storage |
|
||||
| **AWS EKS** | `gp3` or `gp2` | General Purpose SSD |
|
||||
| **Google GKE** | `pd-ssd` | SSD Persistent Disk |
|
||||
| **Azure AKS** | `managed-premium` | Premium SSD |
|
||||
|
||||
**Check available storage classes:**
|
||||
|
||||
```bash
|
||||
kubectl get storageclass
|
||||
```
|
||||
|
||||
```bash
|
||||
# Kubernetes Ingress Configuration
|
||||
INGRESS_HOST=app.meds.192.168.1.100.nip.io # Your cluster IP
|
||||
|
||||
# For production with custom domain
|
||||
INGRESS_HOST=meds.yourdomain.com
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
The CouchDB credentials are stored in a Kubernetes secret. **IMPORTANT**: Update the credentials in `couchdb-secret.yaml` with your own secure values before deploying to production.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Frontend Pod │
|
||||
│ ┌─────────────────────────────────┐│
|
||||
│ │ React Application ││
|
||||
│ │ • Authentication Service ││ ← Embedded in frontend
|
||||
│ │ • UI Components ││
|
||||
│ │ • Medication Management ││
|
||||
│ │ • Email Integration ││
|
||||
│ └─────────────────────────────────┘│
|
||||
└─────────────────────────────────────┘
|
||||
↓ HTTP API
|
||||
┌─────────────────────────────────────┐
|
||||
│ CouchDB StatefulSet │
|
||||
│ • User Data & Authentication │
|
||||
│ • Medication Records │
|
||||
│ • Persistent Storage │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- **Monolithic Frontend**: Single container with all functionality
|
||||
- **Database**: CouchDB running as a StatefulSet with persistent storage
|
||||
- **Storage**: Longhorn for persistent volume management
|
||||
- **Networking**: Services configured for proper communication between components
|
||||
|
||||
## Raspberry Pi Compatibility
|
||||
|
||||
All manifests use multi-architecture images and are optimized for ARM architecture commonly used in Raspberry Pi clusters.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The PVC uses Longhorn storage class for persistent storage
|
||||
- CouchDB runs as a StatefulSet for stable network identifiers
|
||||
- Frontend is exposed via LoadBalancer service
|
||||
- CouchDB is exposed via ClusterIP service (internal access only)
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: ${APP_NAME:-rxminder}-config
|
||||
labels:
|
||||
app: ${APP_NAME:-rxminder}
|
||||
data:
|
||||
NODE_ENV: 'production'
|
||||
REACT_APP_API_URL: 'http://couchdb-service:5984'
|
||||
LOG_LEVEL: 'info'
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: ${APP_NAME}-config
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
data:
|
||||
NODE_ENV: "production"
|
||||
REACT_APP_API_URL: "http://${APP_NAME}-couchdb-service:5984"
|
||||
LOG_LEVEL: "info"
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb-pvc
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: ${STORAGE_CLASS}
|
||||
resources:
|
||||
requests:
|
||||
storage: ${STORAGE_SIZE}
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb-pvc
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: ${STORAGE_CLASS}
|
||||
resources:
|
||||
requests:
|
||||
storage: ${STORAGE_SIZE}
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: couchdb-secret
|
||||
labels:
|
||||
app: ${APP_NAME:-rxminder}
|
||||
component: database
|
||||
type: Opaque
|
||||
stringData:
|
||||
# These values will be automatically base64 encoded by Kubernetes
|
||||
# Update these in your .env file before deployment
|
||||
username: ${COUCHDB_USER:-admin}
|
||||
password: ${COUCHDB_PASSWORD:-change-this-secure-password}
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: couchdb-secret
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
type: Opaque
|
||||
stringData:
|
||||
# These values will be automatically base64 encoded by Kubernetes
|
||||
# Update these in your .env file before deployment
|
||||
username: ${COUCHDB_USER}
|
||||
password: ${COUCHDB_PASSWORD}
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb-service
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
selector:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
ports:
|
||||
- name: couchdb
|
||||
port: 5984
|
||||
targetPort: 5984
|
||||
protocol: TCP
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb-service
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
selector:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
ports:
|
||||
- name: couchdb
|
||||
port: 5984
|
||||
targetPort: 5984
|
||||
protocol: TCP
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
serviceName: ${APP_NAME}-couchdb-service
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
containers:
|
||||
- name: couchdb
|
||||
image: couchdb:3.3.2
|
||||
ports:
|
||||
- containerPort: 5984
|
||||
env:
|
||||
- name: COUCHDB_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: username
|
||||
- name: COUCHDB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: password
|
||||
resources:
|
||||
requests:
|
||||
memory: '64Mi'
|
||||
cpu: '30m'
|
||||
limits:
|
||||
memory: '128Mi'
|
||||
cpu: '60m'
|
||||
volumeMounts:
|
||||
- name: couchdb-data
|
||||
mountPath: /opt/couchdb/data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /_up
|
||||
port: 5984
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /_up
|
||||
port: 5984
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: couchdb-data
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
accessModes: ['ReadWriteOnce']
|
||||
storageClassName: ${STORAGE_CLASS}
|
||||
resources:
|
||||
requests:
|
||||
storage: ${STORAGE_SIZE}
|
||||
@@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: ${APP_NAME}-couchdb
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
serviceName: ${APP_NAME}-couchdb-service
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
containers:
|
||||
- name: couchdb
|
||||
image: couchdb:3.3.2
|
||||
ports:
|
||||
- containerPort: 5984
|
||||
env:
|
||||
- name: COUCHDB_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: username
|
||||
- name: COUCHDB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: password
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "30m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "60m"
|
||||
volumeMounts:
|
||||
- name: couchdb-data
|
||||
mountPath: /opt/couchdb/data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /_up
|
||||
port: 5984
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /_up
|
||||
port: 5984
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: couchdb-data
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: database
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
storageClassName: ${STORAGE_CLASS}
|
||||
resources:
|
||||
requests:
|
||||
storage: ${STORAGE_SIZE}
|
||||
@@ -0,0 +1,107 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: db-seed
|
||||
labels:
|
||||
app: rxminder
|
||||
component: database
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: rxminder
|
||||
component: database
|
||||
spec:
|
||||
containers:
|
||||
- name: db-seeder
|
||||
image: couchdb:3.3.2
|
||||
env:
|
||||
- name: COUCHDB_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: username
|
||||
- name: COUCHDB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: couchdb-secret
|
||||
key: password
|
||||
command: ['/bin/sh', '-c']
|
||||
args:
|
||||
- |
|
||||
# Wait for CouchDB to be ready
|
||||
echo "Waiting for CouchDB to be ready..."
|
||||
until curl -f http://couchdb-service:5984/_up 2>/dev/null; do
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Create databases
|
||||
echo "Creating databases..."
|
||||
curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app
|
||||
|
||||
# Create default admin user
|
||||
echo "Creating default admin user..."
|
||||
curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/_users/org.couchdb.user:$COUCHDB_USER \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"name\": \"$COUCHDB_USER\",
|
||||
\"password\": \"$COUCHDB_PASSWORD\",
|
||||
\"roles\": [\"admin\"],
|
||||
\"type\": \"user\"
|
||||
}"
|
||||
|
||||
# Create design documents for views
|
||||
echo "Creating design documents..."
|
||||
curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/medications \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"views": {
|
||||
"by_name": {
|
||||
"map": "function(doc) { if (doc.type === \"medication\") emit(doc.name, doc); }"
|
||||
},
|
||||
"by_user": {
|
||||
"map": "function(doc) { if (doc.type === \"medication\") emit(doc.userId, doc); }"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/reminders \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"views": {
|
||||
"by_medication": {
|
||||
"map": "function(doc) { if (doc.type === \"reminder\") emit(doc.medicationId, doc); }"
|
||||
},
|
||||
"by_user": {
|
||||
"map": "function(doc) { if (doc.type === \"reminder\") emit(doc.userId, doc); }"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# Create a sample user document for reference
|
||||
# Create design document for authentication users
|
||||
curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/auth \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"views": {
|
||||
"by_username": {
|
||||
"map": "function(doc) { if (doc.type === \"user\" && doc.username) emit(doc.username, doc); }"
|
||||
},
|
||||
"by_email": {
|
||||
"map": "function(doc) { if (doc.type === \"user\" && doc.email) emit(doc.email, doc); }"
|
||||
}
|
||||
}
|
||||
}'
|
||||
echo "Creating sample user document..."
|
||||
curl -X POST http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"type": "user",
|
||||
"name": "sample_user",
|
||||
"email": "user@example.com",
|
||||
"createdAt": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}'
|
||||
|
||||
echo "Database seeding completed with default admin user"
|
||||
restartPolicy: Never
|
||||
backoffLimit: 4
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ${APP_NAME}-frontend
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: frontend
|
||||
image: ${DOCKER_IMAGE}
|
||||
ports:
|
||||
- containerPort: 80
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${APP_NAME}-config
|
||||
resources:
|
||||
requests:
|
||||
memory: '32Mi'
|
||||
cpu: '20m'
|
||||
limits:
|
||||
memory: '64Mi'
|
||||
cpu: '40m'
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ${APP_NAME}-frontend
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: frontend
|
||||
image: gitea-http.taildb3494.ts.net/will/meds:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${APP_NAME}-config
|
||||
resources:
|
||||
requests:
|
||||
memory: "32Mi"
|
||||
cpu: "20m"
|
||||
limits:
|
||||
memory: "64Mi"
|
||||
cpu: "40m"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${APP_NAME}-frontend-service
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
selector:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${APP_NAME}-frontend-service
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
spec:
|
||||
selector:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: frontend-hpa
|
||||
labels:
|
||||
app: rxminder
|
||||
component: frontend
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: frontend
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 50
|
||||
@@ -0,0 +1,29 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: frontend-ingress
|
||||
labels:
|
||||
app: rxminder
|
||||
component: frontend
|
||||
annotations: {}
|
||||
# Add SSL redirect if using HTTPS
|
||||
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# Uncomment for HTTPS with cert-manager
|
||||
# tls:
|
||||
# - hosts:
|
||||
# - ${INGRESS_HOST}
|
||||
# secretName: frontend-tls
|
||||
rules:
|
||||
- host: app.meds.192.168.153.243.nip.io # TODO: Make configurable via deployment script
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: frontend-service
|
||||
port:
|
||||
number: 80
|
||||
@@ -0,0 +1,29 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ${APP_NAME}-ingress
|
||||
labels:
|
||||
app: ${APP_NAME}
|
||||
component: frontend
|
||||
annotations:
|
||||
# Add SSL redirect if using HTTPS
|
||||
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# Uncomment for HTTPS with cert-manager
|
||||
# tls:
|
||||
# - hosts:
|
||||
# - ${INGRESS_HOST}
|
||||
# secretName: frontend-tls
|
||||
rules:
|
||||
- host: ${INGRESS_HOST}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: ${APP_NAME}-frontend-service
|
||||
port:
|
||||
number: 80
|
||||
@@ -0,0 +1,68 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: frontend-policy
|
||||
labels:
|
||||
app: rxminder
|
||||
component: frontend
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
component: frontend
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
component: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
egress:
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
component: database
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5984
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
component: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: database-policy
|
||||
labels:
|
||||
app: rxminder
|
||||
component: database
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
component: database
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
component: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5984
|
||||
egress:
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
component: database
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5984
|
||||
Reference in New Issue
Block a user