From 3153fd8a746a0121cdabc3abfbc60568d8a7aea3 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Mon, 23 Feb 2026 20:11:56 +0330 Subject: [PATCH] feat: add PersistentVolume for CMS uploads + apply manifests in CI/CD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add k8s/staging/ and k8s/production/ deployment manifests - PVC 20Gi for /app/Uploads (file uploads persist across pod restarts) - FileStorage__UploadPath env var set to /app/Uploads - Replicas reduced to 1 (ReadWriteOnce PVC) - Pipelines now: create namespace → apply manifests → restart/update --- .gitea/workflows/kub-deploy.yml | 12 ++- .gitea/workflows/prod-deploy.yml | 12 ++- k8s/production/cms-deployment.yaml | 155 +++++++++++++++++++++++++++++ k8s/staging/cms-deployment.yaml | 155 +++++++++++++++++++++++++++++ 4 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 k8s/production/cms-deployment.yaml create mode 100644 k8s/staging/cms-deployment.yaml diff --git a/.gitea/workflows/kub-deploy.yml b/.gitea/workflows/kub-deploy.yml index 8ba2a3f..0e3c999 100644 --- a/.gitea/workflows/kub-deploy.yml +++ b/.gitea/workflows/kub-deploy.yml @@ -86,8 +86,16 @@ jobs: - name: Deploy to Kubernetes run: | export SSHPASS="${{ secrets.SERVER_PASSWORD }}" + + # Copy K8s manifests to server + sshpass -e scp -o StrictHostKeyChecking=no k8s/staging/cms-deployment.yaml root@${{ env.K8S_SERVER }}:/tmp/cms-deployment.yaml + + # Apply manifests and restart sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} " - kubectl rollout restart deployment/cms - kubectl rollout status deployment/cms --timeout=180s + kubectl create namespace foursat --dry-run=client -o yaml | kubectl apply -f - && + kubectl apply -f /tmp/cms-deployment.yaml && + kubectl rollout restart deployment/cms -n foursat && + kubectl rollout status deployment/cms -n foursat --timeout=180s && + rm -f /tmp/cms-deployment.yaml " echo "✅ Deployed!" diff --git a/.gitea/workflows/prod-deploy.yml b/.gitea/workflows/prod-deploy.yml index 9788b35..af59001 100644 --- a/.gitea/workflows/prod-deploy.yml +++ b/.gitea/workflows/prod-deploy.yml @@ -86,8 +86,16 @@ jobs: - name: Deploy to Production run: | export SSHPASS="${{ secrets.SERVER_PASSWORD }}" + + # Copy K8s manifests to server + sshpass -e scp -o StrictHostKeyChecking=no k8s/production/cms-deployment.yaml root@${{ env.K8S_SERVER }}:/tmp/cms-deployment.yaml + + # Apply manifests and update image sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} " - kubectl set image deployment/cms cms=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - kubectl rollout status deployment/cms --timeout=300s + kubectl create namespace foursat --dry-run=client -o yaml | kubectl apply -f - && + kubectl apply -f /tmp/cms-deployment.yaml && + kubectl set image deployment/cms cms=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} -n foursat && + kubectl rollout status deployment/cms -n foursat --timeout=300s && + rm -f /tmp/cms-deployment.yaml " echo "✅ Deployed to Production!" diff --git a/k8s/production/cms-deployment.yaml b/k8s/production/cms-deployment.yaml new file mode 100644 index 0000000..374a0ce --- /dev/null +++ b/k8s/production/cms-deployment.yaml @@ -0,0 +1,155 @@ +--- +# CMS Uploads PersistentVolumeClaim (Production) +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: cms-uploads-pvc + namespace: foursat + labels: + app: cms +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi + +--- +# CMS Microservice Deployment (Production) +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cms + namespace: foursat + labels: + app: cms +spec: + replicas: 1 + selector: + matchLabels: + app: cms + template: + metadata: + labels: + app: cms + spec: + containers: + - name: cms + image: git.se.kbs1.ir/admin/cms:prod + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + env: + - name: ASPNETCORE_ENVIRONMENT + value: "Production" + - name: ASPNETCORE_URLS + value: "http://+:8080" + - name: Kestrel__EndpointDefaults__Protocols + value: "Http1AndHttp2" + - name: FileStorage__UploadPath + value: "/app/Uploads" + - name: ConnectionStrings__DefaultConnection + valueFrom: + secretKeyRef: + name: postgres-secret + key: connection-string + - name: Email__Host + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-host + - name: Email__Port + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-port + - name: Email__Username + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-username + - name: Email__Password + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-password + - name: Kavenegar__ApiKey + valueFrom: + secretKeyRef: + name: sms-secret + key: api-key + volumeMounts: + - name: cms-uploads + mountPath: /app/Uploads + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "1Gi" + cpu: "1000m" + 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 + volumes: + - name: cms-uploads + persistentVolumeClaim: + claimName: cms-uploads-pvc + +--- +# CMS Service (Production) +apiVersion: v1 +kind: Service +metadata: + name: cms-svc + namespace: foursat +spec: + selector: + app: cms + ports: + - name: http + port: 8080 + targetPort: 8080 + type: ClusterIP + +--- +# CMS Ingress (Production) +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cms-ingress + namespace: foursat + annotations: + kubernetes.io/ingress.class: "nginx" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/ssl-redirect: "true" +spec: + tls: + - hosts: + - cms.kbs1.ir + secretName: cms-tls + rules: + - host: cms.kbs1.ir + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: cms-svc + port: + number: 8080 diff --git a/k8s/staging/cms-deployment.yaml b/k8s/staging/cms-deployment.yaml new file mode 100644 index 0000000..7ac719f --- /dev/null +++ b/k8s/staging/cms-deployment.yaml @@ -0,0 +1,155 @@ +--- +# CMS Uploads PersistentVolumeClaim +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: cms-uploads-pvc + namespace: foursat + labels: + app: cms +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi + +--- +# CMS Microservice Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cms + namespace: foursat + labels: + app: cms +spec: + replicas: 1 + selector: + matchLabels: + app: cms + template: + metadata: + labels: + app: cms + spec: + containers: + - name: cms + image: git.se.kbs1.ir/admin/cms:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + env: + - name: ASPNETCORE_ENVIRONMENT + value: "Production" + - name: ASPNETCORE_URLS + value: "http://+:8080" + - name: Kestrel__EndpointDefaults__Protocols + value: "Http1AndHttp2" + - name: FileStorage__UploadPath + value: "/app/Uploads" + - name: ConnectionStrings__DefaultConnection + valueFrom: + secretKeyRef: + name: postgres-secret + key: connection-string + - name: Email__Host + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-host + - name: Email__Port + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-port + - name: Email__Username + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-username + - name: Email__Password + valueFrom: + secretKeyRef: + name: email-secret + key: smtp-password + - name: Kavenegar__ApiKey + valueFrom: + secretKeyRef: + name: sms-secret + key: api-key + volumeMounts: + - name: cms-uploads + mountPath: /app/Uploads + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "1Gi" + cpu: "1000m" + 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 + volumes: + - name: cms-uploads + persistentVolumeClaim: + claimName: cms-uploads-pvc + +--- +# CMS Service +apiVersion: v1 +kind: Service +metadata: + name: cms-svc + namespace: foursat +spec: + selector: + app: cms + ports: + - name: http + port: 8080 + targetPort: 8080 + type: ClusterIP + +--- +# CMS Ingress +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cms-ingress + namespace: foursat + annotations: + kubernetes.io/ingress.class: "nginx" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/ssl-redirect: "true" +spec: + tls: + - hosts: + - cms.se.kbs1.ir + secretName: cms-tls + rules: + - host: cms.se.kbs1.ir + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: cms-svc + port: + number: 8080