Files
docs/kubernetes-deployment-guide.md
T
masoodafar-web 6220049161 feat: Enhance CMS Microservice with SystemConstants and SmsTemplates
- Added SystemConstants class to centralize hardcoded values for club configuration, commission configuration, and package amounts.
- Introduced SmsTemplates class to manage SMS message templates for various user notifications.
- Implemented automatic SMS sending for Daya Loan approval notifications.
- Updated BackOffice UI to include App Version management features.
- Fixed mapping issues in Mapster profiles for improved data handling.
- Updated changelog and documentation to reflect recent changes and configurations.
2025-12-27 05:07:33 +03:30

10 KiB

Kubernetes Deployment Example for CMS API

🔐 ایجاد Secrets

برای Staging:

kubectl create secret generic cms-secrets \
  --from-literal=db-connection="Data Source=STAGING_SERVER;Initial Catalog=Foursat_Staging;User ID=sa;Password=STAGING_PASSWORD;MultipleActiveResultSets=True;Encrypt=False" \
  --from-literal=jwt-key="YOUR_STAGING_JWT_KEY" \
  --from-literal=kavenegar-key="YOUR_STAGING_KAVENEGAR_KEY" \
  --from-literal=daya-key="YOUR_STAGING_DAYA_KEY" \
  --from-literal=chatika-key="YOUR_STAGING_CHATIKA_KEY" \
  --from-literal=sentry-dsn="YOUR_STAGING_SENTRY_DSN" \
  --from-literal=slack-webhook="YOUR_STAGING_SLACK_WEBHOOK" \
  --from-literal=seq-key="YOUR_STAGING_SEQ_KEY" \
  --namespace=staging

برای Production:

kubectl create secret generic cms-secrets \
  --from-literal=db-connection="Data Source=PRODUCTION_SERVER;Initial Catalog=Foursat;User ID=sa;Password=PRODUCTION_PASSWORD;MultipleActiveResultSets=True;Encrypt=True" \
  --from-literal=jwt-key="YOUR_PRODUCTION_JWT_KEY" \
  --from-literal=kavenegar-key="YOUR_PRODUCTION_KAVENEGAR_KEY" \
  --from-literal=daya-key="YOUR_PRODUCTION_DAYA_KEY" \
  --from-literal=chatika-key="YOUR_PRODUCTION_CHATIKA_KEY" \
  --from-literal=sentry-dsn="YOUR_PRODUCTION_SENTRY_DSN" \
  --from-literal=slack-webhook="YOUR_PRODUCTION_SLACK_WEBHOOK" \
  --from-literal=seq-key="YOUR_PRODUCTION_SEQ_KEY" \
  --from-literal=smtp-username="production@domain.com" \
  --from-literal=smtp-password="YOUR_SMTP_PASSWORD" \
  --namespace=production

📄 Deployment Manifest

cms-deployment-staging.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cms-api
  namespace: staging
  labels:
    app: cms-api
    environment: staging
spec:
  replicas: 2
  selector:
    matchLabels:
      app: cms-api
  template:
    metadata:
      labels:
        app: cms-api
        environment: staging
    spec:
      containers:
      - name: cms
        image: your-registry/cms-api:staging-latest
        ports:
        - containerPort: 5000
          name: grpc
          protocol: TCP
        - containerPort: 8080
          name: http
          protocol: TCP
        env:
        # Environment
        - name: ASPNETCORE_ENVIRONMENT
          value: "Staging"
        
        # Database
        - name: ConnectionStrings__DefaultConnection
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: db-connection
        
        # JWT
        - name: JwtSecurityKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: jwt-key
        
        # SMS
        - name: Sms__KavenegarApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: kavenegar-key
        
        # Daya API
        - name: DayaApi__MerchantPermissionKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: daya-key
        
        # Chatika
        - name: Chatika__ApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: chatika-key
        
        # Monitoring
        - name: Monitoring__SentryDsn
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: sentry-dsn
        
        - name: Monitoring__SlackWebhookUrl
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: slack-webhook
        
        # Seq
        - name: Seq__ApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: seq-key
        
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: cms-api-service
  namespace: staging
spec:
  selector:
    app: cms-api
  ports:
  - name: grpc
    port: 5000
    targetPort: 5000
    protocol: TCP
  - name: http
    port: 8080
    targetPort: 8080
    protocol: TCP
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cms-api-ingress
  namespace: staging
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - cms-staging.domain.com
    secretName: cms-staging-tls
  rules:
  - host: cms-staging.domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: cms-api-service
            port:
              number: 8080

cms-deployment-production.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cms-api
  namespace: production
  labels:
    app: cms-api
    environment: production
spec:
  replicas: 3  # بیشتر برای production
  selector:
    matchLabels:
      app: cms-api
  template:
    metadata:
      labels:
        app: cms-api
        environment: production
    spec:
      containers:
      - name: cms
        image: your-registry/cms-api:production-latest
        ports:
        - containerPort: 5000
          name: grpc
        - containerPort: 8080
          name: http
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Production"
        
        # همان تنظیمات secrets مثل staging
        - name: ConnectionStrings__DefaultConnection
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: db-connection
        
        - name: JwtSecurityKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: jwt-key
        
        - name: Sms__KavenegarApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: kavenegar-key
        
        - name: DayaApi__MerchantPermissionKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: daya-key
        
        - name: Chatika__ApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: chatika-key
        
        - name: Monitoring__SentryDsn
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: sentry-dsn
        
        - name: Monitoring__SlackWebhookUrl
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: slack-webhook
        
        - name: Seq__ApiKey
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: seq-key
        
        # Email credentials for production
        - name: Email__SmtpUsername
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: smtp-username
        
        - name: Email__SmtpPassword
          valueFrom:
            secretKeyRef:
              name: cms-secrets
              key: smtp-password
        
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: cms-api-service
  namespace: production
spec:
  selector:
    app: cms-api
  ports:
  - name: grpc
    port: 5000
    targetPort: 5000
  - name: http
    port: 8080
    targetPort: 8080
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cms-api-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - cms.domain.com
    secretName: cms-production-tls
  rules:
  - host: cms.domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: cms-api-service
            port:
              number: 8080

🚀 Deploy Commands

Staging:

kubectl apply -f cms-deployment-staging.yaml
kubectl get pods -n staging
kubectl logs -f deployment/cms-api -n staging

Production:

kubectl apply -f cms-deployment-production.yaml
kubectl get pods -n production
kubectl logs -f deployment/cms-api -n production

🔄 CI/CD Integration

GitLab CI Example:

stages:
  - build
  - deploy-staging
  - deploy-production

variables:
  DOCKER_REGISTRY: your-registry.azurecr.io
  IMAGE_NAME: cms-api

build:
  stage: build
  script:
    - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA .
    - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA

deploy-staging:
  stage: deploy-staging
  only:
    - kub-stage
  script:
    - kubectl set image deployment/cms-api cms=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA -n staging
    - kubectl rollout status deployment/cms-api -n staging

deploy-production:
  stage: deploy-production
  only:
    - production
  when: manual  # نیاز به تأیید دستی
  script:
    - kubectl set image deployment/cms-api cms=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA -n production
    - kubectl rollout status deployment/cms-api -n production

📋 Monitoring

Check deployment status:

kubectl get deployments -n staging
kubectl get pods -n staging -l app=cms-api
kubectl describe pod <pod-name> -n staging

View logs:

kubectl logs -f deployment/cms-api -n staging
kubectl logs --tail=100 deployment/cms-api -n production

Check configuration:

kubectl exec -it <pod-name> -n staging -- env | grep ASPNETCORE