# 🚀 استقرار، CI/CD و زیرساخت > **منابع ادغام‌شده:** `CICD-PIPELINE-GUIDE.md`, `DEPLOYMENT-README.md`, `INFRASTRUCTURE-GUIDE.md`, `INGRESS-NGINX-WARNING.md`, `OFFLINE-DEPLOYMENT-GUIDE.md`, `SERVER-MIRRORS-CONFIG.md` > **آخرین بروزرسانی:** اسفند ۱۴۰۴ --- ## ۱. سرورها | سرور | IP | نقش | منابع | |------|-----|------|--------| | **Staging** | 194.5.195.53 | توسعه + تست | 4 CPU, 8GB RAM | | **Production** | 45.149.79.127 | محیط نهایی | 4 CPU, 16GB RAM | | **Git** | git.se.kbs1.ir | Gitea (مخازن کد) | — | | **Registry** | داخلی | Docker Registry / Nexus | — | --- ## ۲. Docker و Container ### ۲.۱ سرویس‌ها ```yaml # docker-compose.yml (production) services: cms: image: foursat/cms:latest ports: ["5001:5001"] # gRPC environment: - ConnectionStrings__Default=Server=db;Database=FourSatCMS - ASPNETCORE_ENVIRONMENT=Production depends_on: [db] backoffice: image: foursat/backoffice:latest ports: ["5002:80"] # Static Blazor WASM frontoffice: image: foursat/frontoffice:latest ports: ["5003:5003"] # Blazor Server db: image: mcr.microsoft.com/mssql/server:2022-CU16-ubuntu-22.04 ports: ["1433:1433"] volumes: ["sqldata:/var/opt/mssql"] nexus: # NuGet + Docker registry image: sonatype/nexus3 ports: ["8081:8081"] volumes: sqldata: ``` ### ۲.۲ Dockerfile (CMS) ```dockerfile FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base WORKDIR /app EXPOSE 5001 FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src COPY ["CMSMicroservice/CMSMicroservice.csproj", "CMSMicroservice/"] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish FROM base AS final COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "CMSMicroservice.dll"] ``` --- ## ۳. Kubernetes ### ۳.۱ Manifests ساختار ``` deployment/k8s-manifests/ ├── cms-deployment.yaml ├── cms-service.yaml ├── backoffice-deployment.yaml ├── backoffice-service.yaml ├── frontoffice-deployment.yaml ├── frontoffice-service.yaml ├── db-statefulset.yaml ├── db-service.yaml ├── ingress.yaml ├── configmap.yaml └── secrets.yaml ``` ### ۳.۲ مثال Deployment ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: cms namespace: foursat spec: replicas: 2 selector: matchLabels: app: cms template: spec: containers: - name: cms image: foursat/cms:latest ports: - containerPort: 5001 resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: grpc: port: 5001 initialDelaySeconds: 15 readinessProbe: grpc: port: 5001 ``` ### ۳.۳ Ingress ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: foursat-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "50m" spec: rules: - host: foursat.ir http: paths: - path: / backend: service: name: frontoffice port: { number: 5003 } - path: /admin backend: service: name: backoffice port: { number: 80 } ``` > ⚠️ **هشدار:** Ingress-nginx نسخه‌های قبل از 1.9.0 مشکل امنیتی CVE-2023-5044 دارند. حتماً بروزرسانی کنید. --- ## ۴. CI/CD Pipeline ### ۴.۱ Gitea Actions Workflow ```yaml name: Build and Deploy on: push: branches: [kub-stage, production] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '9.0.x' - name: Restore run: dotnet restore - name: Build run: dotnet build --no-restore -c Release - name: Test run: dotnet test --no-build -c Release - name: Docker Build & Push run: | docker build -t $REGISTRY/foursat/cms:${{ github.sha }} . docker push $REGISTRY/foursat/cms:${{ github.sha }} - name: Deploy to K8s if: github.ref == 'refs/heads/production' run: | kubectl set image deployment/cms cms=$REGISTRY/foursat/cms:${{ github.sha }} ``` ### ۴.۲ شاخه‌ها | شاخه | محیط | Deploy | |------|------|--------| | `kub-stage` | Staging (194.5.195.53) | Auto | | `production` | Production (45.149.79.127) | Manual trigger | | `main` | — | Development only | --- ## ۵. استقرار آفلاین (Offline Deployment) ### ۵.۱ فلوی آماده‌سازی ``` سرور اینترنت‌دار: 1. pull-base-images.sh → دانلود Docker images 2. cache-nuget-packages.sh → دانلود NuGet packages 3. save-images.sh → ذخیره تصاویر به tar 4. بسته‌بندی همه فایل‌ها انتقال فیزیکی (USB/HDD): tar files + nuget packages + k8s manifests سرور آفلاین: 1. load-images.sh → بارگذاری تصاویر 2. setup-nexus-complete.sh → راه‌اندازی Nexus (NuGet proxy) 3. build-all-offline.sh → بیلد با Nexus محلی 4. k8s-deploy.sh → استقرار در Kubernetes ``` ### ۵.۲ اسکریپت‌های کلیدی | اسکریپت | کاربرد | |----------|--------| | `pull-base-images.sh` | دانلود ۱۵+ Docker image پایه | | `save-images.sh` | Export به tar (4-8 GB) | | `load-images.sh` | Import از tar به Docker | | `cache-nuget-packages.sh` | دانلود NuGet offline | | `setup-nexus-complete.sh` | راه‌اندازی NuGet proxy | | `build-all-offline.sh` | بیلد بدون اینترنت | | `k8s-deploy.sh` | Deploy تمام سرویس‌ها | | `k8s-health-check.sh` | بررسی سلامت سرویس‌ها | --- ## ۶. Nexus Repository Manager ### ۶.۱ نقش ``` Nexus (داخلی): ├── NuGet proxy → cache.nuget.org packages ├── NuGet hosted → بسته‌های proto داخلی ├── Docker proxy → cache Docker Hub images └── Docker hosted → تصاویر داخلی FourSat ``` ### ۶.۲ NuGet.config ```xml ``` --- ## ۷. Mirror و Cache ### ۷.۱ Docker Mirror ```json // /etc/docker/daemon.json { "registry-mirrors": [ "https://mirror.gcr.io", "https://docker.arvancloud.ir" ], "insecure-registries": [ "localhost:8082" ] } ``` ### ۷.۲ NuGet Mirror ``` Primary: nuget.org Fallback: Nexus local proxy Proto packages: BaGet (internal) at http://localhost:5555 ``` --- ## ۸. Proto Packages (NuGet) ### ۸.۱ فلوی بسته‌بندی ``` CMS/src/Protos/*.proto │ ▼ pack-protos.sh → dotnet pack → .nupkg │ ▼ push to BaGet/Nexus │ ▼ BackOffice + FrontOffice → dotnet restore → مصرف proto ``` ### ۸.۲ نام بسته ```xml ``` --- ## ۹. مانیتورینگ و Health Check ```bash # k8s-health-check.sh kubectl get pods -n foursat kubectl top pods -n foursat kubectl logs deployment/cms -n foursat --tail=50 # تست سرویس‌ها grpcurl -plaintext localhost:5001 list # لیست سرویس‌ها grpcurl -plaintext localhost:5001 grpc.health.v1.Health/Check # Health curl http://localhost:5002/index.html # BackOffice curl http://localhost:5003/ # FrontOffice ```