guides. Here's what has been created: 📁 Azure Managed Deployment Structure documentation/deployment-guides/azure-managed/ ├── README.md # Overview and architecture ├── 00-prerequisites-managed.md # Azure prerequisites setup ├── 01-aks-managed-deployment.md # AKS deployment guide ├── 02-container-instances-deployment.md # Container Instances guide ├── 03-production-managed-setup.md # Production hardening ├── kubernetes-manifests/ # Kubernetes YAML files │ ├── namespace.yaml # Namespace and quotas │ ├── storage.yaml # Azure Files storage │ ├── configmap.yaml # Configuration │ ├── secrets.yaml # Key Vault integration │ ├── erpnext-backend.yaml # Backend deployment │ ├── erpnext-frontend.yaml # Frontend deployment │ ├── erpnext-workers.yaml # Workers and scheduler │ ├── ingress.yaml # Ingress configuration │ └── jobs.yaml # Init and backup jobs └── scripts/ # Automation scripts ├── deploy-managed.sh # AKS deployment script └── container-instances-deploy.sh # ACI deployment script 🔄 Key Azure Service Mappings | GCP Service | Azure Equivalent | Notes | |----------------------|--------------------------------------|------------------------------- ---------------------------| | Cloud SQL (MySQL) | Azure Database for PostgreSQL | Using PostgreSQL instead of MySQL for better performance | | Memorystore (Redis) | Azure Cache for Redis | Full compatibility with SSL/TLS | | Cloud Storage | Azure Storage (Blob & Files) | Using Azure Files for shared storage | | GKE | AKS (Azure Kubernetes Service) | Full Kubernetes compatibility | | Cloud Run | Azure Container Instances | Serverless container platform | | Secret Manager | Azure Key Vault | Integrated secrets management | | Cloud IAM | Azure AD & Managed Identity | Enterprise-grade identity | | Stackdriver | Azure Monitor & Application Insights | Comprehensive monitoring | | Cloud CDN | Azure CDN | Global content delivery | | Cloud Load Balancing | Azure Application Gateway | L7 load balancing with WAF | ✨ Key Features 1. Managed Services - Azure Database for PostgreSQL with high availability - Azure Cache for Redis with SSL/TLS encryption - Azure Storage for file management - Azure Key Vault for secrets 2. Deployment Options - AKS: Full Kubernetes control with auto-scaling - Container Instances: Simpler serverless deployment 3. Security - Managed Identity for passwordless authentication - Private endpoints for database and Redis - Network security groups and firewall rules - SSL/TLS encryption everywhere 4. Production Ready - Automated backups with geo-redundancy - Monitoring with Azure Monitor - Auto-scaling configurations - Disaster recovery setup 5. Automation - One-command deployment scripts - Environment validation - Health checks and diagnostics - Backup automation 🚀 Quick Start # Prerequisites cd documentation/deployment-guides/azure-managed/ # Follow 00-prerequisites-managed.md # Option 1: Deploy to AKS ./scripts/deploy-managed.sh deploy # Option 2: Deploy to Container Instances ./scripts/container-instances-deploy.sh deploy 💰 Cost Comparison | Deployment Size | Azure (Monthly) | GCP (Monthly) | |-------------------|-----------------|---------------| | Small (<50 users) | ~ | ~ | | Medium (50-200) | ~ | ~ | | Large (200+) | ~,823 | ~,794 | The Azure deployment uses PostgreSQL instead of MySQL, which provides better performance and features, and includes Azure-specific optimizations for the cloud-native environment.
194 lines
4.5 KiB
YAML
194 lines
4.5 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: erpnext-frontend
|
|
namespace: erpnext
|
|
labels:
|
|
app: erpnext-frontend
|
|
component: frontend
|
|
version: v14
|
|
spec:
|
|
replicas: 2
|
|
revisionHistoryLimit: 5
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate:
|
|
maxSurge: 1
|
|
maxUnavailable: 0
|
|
selector:
|
|
matchLabels:
|
|
app: erpnext-frontend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: erpnext-frontend
|
|
component: frontend
|
|
annotations:
|
|
prometheus.io/scrape: "true"
|
|
prometheus.io/port: "8080"
|
|
prometheus.io/path: "/metrics"
|
|
spec:
|
|
affinity:
|
|
podAntiAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
podAffinityTerm:
|
|
labelSelector:
|
|
matchExpressions:
|
|
- key: app
|
|
operator: In
|
|
values:
|
|
- erpnext-frontend
|
|
topologyKey: kubernetes.io/hostname
|
|
volumes:
|
|
- name: sites
|
|
persistentVolumeClaim:
|
|
claimName: erpnext-sites
|
|
- name: assets
|
|
persistentVolumeClaim:
|
|
claimName: erpnext-assets
|
|
- name: nginx-config
|
|
configMap:
|
|
name: nginx-config
|
|
containers:
|
|
- name: frontend
|
|
image: frappe/erpnext-nginx:v14
|
|
imagePullPolicy: Always
|
|
ports:
|
|
- containerPort: 8080
|
|
name: http
|
|
protocol: TCP
|
|
volumeMounts:
|
|
- name: sites
|
|
mountPath: /home/frappe/frappe-bench/sites
|
|
readOnly: true
|
|
- name: assets
|
|
mountPath: /usr/share/nginx/html/assets
|
|
readOnly: true
|
|
- name: nginx-config
|
|
mountPath: /etc/nginx/nginx.conf
|
|
subPath: nginx.conf
|
|
env:
|
|
- name: BACKEND
|
|
value: erpnext-backend:8000
|
|
- name: FRAPPE_SITE_NAME_HEADER
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: erpnext-config
|
|
key: FRAPPE_SITE_NAME_HEADER
|
|
- name: SOCKETIO
|
|
value: erpnext-websocket:9000
|
|
- name: UPSTREAM_REAL_IP_ADDRESS
|
|
value: "127.0.0.1"
|
|
- name: UPSTREAM_REAL_IP_HEADER
|
|
value: "X-Forwarded-For"
|
|
- name: UPSTREAM_REAL_IP_RECURSIVE
|
|
value: "on"
|
|
- name: PROXY_READ_TIMEOUT
|
|
value: "120"
|
|
- name: CLIENT_MAX_BODY_SIZE
|
|
value: "50m"
|
|
resources:
|
|
requests:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8080
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8080
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
lifecycle:
|
|
preStop:
|
|
exec:
|
|
command: ["/bin/sh", "-c", "sleep 15"]
|
|
imagePullSecrets:
|
|
- name: acr-secret
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: erpnext-frontend
|
|
namespace: erpnext
|
|
labels:
|
|
app: erpnext-frontend
|
|
annotations:
|
|
service.beta.kubernetes.io/azure-load-balancer-internal: "false"
|
|
spec:
|
|
type: ClusterIP
|
|
sessionAffinity: ClientIP
|
|
sessionAffinityConfig:
|
|
clientIP:
|
|
timeoutSeconds: 10800
|
|
ports:
|
|
- port: 8080
|
|
targetPort: 8080
|
|
protocol: TCP
|
|
name: http
|
|
selector:
|
|
app: erpnext-frontend
|
|
---
|
|
apiVersion: autoscaling/v2
|
|
kind: HorizontalPodAutoscaler
|
|
metadata:
|
|
name: erpnext-frontend-hpa
|
|
namespace: erpnext
|
|
spec:
|
|
scaleTargetRef:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
name: erpnext-frontend
|
|
minReplicas: 2
|
|
maxReplicas: 10
|
|
metrics:
|
|
- type: Resource
|
|
resource:
|
|
name: cpu
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 70
|
|
- type: Resource
|
|
resource:
|
|
name: memory
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 80
|
|
behavior:
|
|
scaleUp:
|
|
stabilizationWindowSeconds: 60
|
|
policies:
|
|
- type: Percent
|
|
value: 50
|
|
periodSeconds: 60
|
|
selectPolicy: Max
|
|
scaleDown:
|
|
stabilizationWindowSeconds: 300
|
|
policies:
|
|
- type: Percent
|
|
value: 25
|
|
periodSeconds: 60
|
|
selectPolicy: Min
|
|
---
|
|
apiVersion: policy/v1
|
|
kind: PodDisruptionBudget
|
|
metadata:
|
|
name: erpnext-frontend-pdb
|
|
namespace: erpnext
|
|
spec:
|
|
minAvailable: 1
|
|
selector:
|
|
matchLabels:
|
|
app: erpnext-frontend |