# 🚀 راهنمای دیپلوی آفلاین FourSat ## 📋 خلاصه این داکیومنت تنظیمات انجام شده برای دیپلوی کاملاً آفلاین پروژه FourSat را شرح می‌دهد. --- ## 🏗️ معماری ``` ┌─────────────────────────────────────────────────────────────────┐ │ سرور 194.5.195.53 │ ├─────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Gitea │ │ Nexus │ │ K3s │ │ │ │ (Git Host) │ │ (Registry) │ │ (Kubernetes) │ │ │ │ │ │ │ │ │ │ │ │ gitea-svc: │ │ :32081 UI │ │ kubectl │ │ │ │ 3000 │ │ :32082 Docker│ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Registry │ │ Gitea Runner │ │ │ │ (Apps) │ │ (CI/CD) │ │ │ │ :30080 │ │ │ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 🔧 اطلاعات دسترسی | سرویس | آدرس | یوزر | پسورد | |-------|------|------|-------| | **سرور SSH** | `194.5.195.53` | `root` | `87zH26nbqT` | | **Nexus UI** | `http://194.5.195.53:32081` | `admin` | `87zH26nbqT` | | **Nexus Docker** | `194.5.195.53:32082` | `admin` | `87zH26nbqT` | | **App Registry** | `194.5.195.53:30080` | `admin` | `87zH26nbqT` | | **NuGet Feed** | `http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json` | - | - | --- ## 🐳 ایمیج‌های کش شده در Nexus این ایمیج‌ها در `194.5.195.53:32082` ذخیره شدن و نیازی به اینترنت ندارن: | ایمیج | استفاده | |-------|---------| | `docker-sshpass:latest` | ایمیج اصلی CI/CD (docker + sshpass) | | `docker:latest` | Docker in Docker | | `dotnet/sdk:9.0` | بیلد .NET پروژه‌ها | | `dotnet/aspnet:9.0` | Runtime .NET | | `nginx:alpine` | فرانت‌اند‌ها | --- ## 📦 پکیج‌های NuGet ~500 پکیج .NET در Nexus NuGet hosted repository کش شدن: - `http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json` ### NuGet.config نمونه: ```xml ``` --- ## 🔄 CI/CD Pipeline ### ساختار Workflow (یکسان برای همه پروژه‌ها) ```yaml name: Build and Deploy to Kubernetes on: push: branches: - kub-stage env: REGISTRY: 194.5.195.53:30080 IMAGE_NAME: admin/ K8S_SERVER: 194.5.195.53 jobs: build-and-deploy: runs-on: ubuntu-latest container: image: 194.5.195.53:32082/docker-sshpass:latest # ✅ آفلاین options: --privileged steps: - name: Start Docker daemon run: | mkdir -p /etc/docker cat > /etc/docker/daemon.json << 'DAEMON' { "insecure-registries": ["194.5.195.53:30080", "194.5.195.53:32500", "194.5.195.53:32082"] } DAEMON dockerd & for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break || sleep 2; done - name: Checkout code run: | git clone --depth 1 --branch kub-stage http://gitea-svc:3000/admin/.git . # فقط برای پروژه‌های .NET API (CMS, BackOffice.BFF, FrontOffice.BFF) - name: Publish Protobuf packages run: | docker run --rm -v $(pwd):/src -w /src \ 194.5.195.53:32082/dotnet/sdk:9.0 sh -c ' for proj in $(find . -name "*Protobuf*.csproj" -type f); do dotnet restore "$proj" dotnet build "$proj" -c Release --no-restore dotnet pack "$proj" -c Release --no-build -o "$(dirname $proj)/nupkg" for nupkg in $(dirname $proj)/nupkg/*.nupkg; do [ -f "$nupkg" ] && dotnet nuget push "$nupkg" \ --source "http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json" \ --api-key "admin:87zH26nbqT" \ --skip-duplicate --allow-insecure-connections || true done done ' - name: Build Docker Image run: | docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest . - name: Push to Registry run: | echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u admin --password-stdin docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - name: Deploy to Kubernetes run: | export SSHPASS="${{ secrets.SERVER_PASSWORD }}" sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} " kubectl rollout restart deployment/ kubectl rollout status deployment/ --timeout=180s " ``` --- ## 📂 پروژه‌ها | پروژه | IMAGE_NAME | Dockerfile | Deployment | Protobuf | |-------|------------|------------|------------|----------| | **CMS** | `admin/cms` | `./Dockerfile` | `cms` | ✅ | | **BackOffice.BFF** | `admin/backoffice-bff` | `src/BackOffice.BFF.WebApi/Dockerfile` | `backoffice-bff` | ✅ | | **FrontOffice.BFF** | `admin/frontoffice-bff` | `src/FrontOffice.BFF.WebApi/Dockerfile` | `frontoffice-bff` | ✅ | | **BackOffice** | `admin/backoffice` | `src/BackOffice/Dockerfile` | `backoffice` | ❌ | | **FrontOffice** | `admin/frontoffice` | `src/FrontOffice.Main/Dockerfile` | `frontoffice` | ❌ | --- ## 🔐 Gitea Secrets این secret ها باید در Gitea تنظیم شوند: ### روش 1: برای هر Repository جداگانه `https://git.se.kbs1.ir/admin//settings/actions/secrets` ### روش 2: برای کل Organization `https://git.se.kbs1.ir/admin/-/settings/actions/secrets` | Secret Name | Value | |-------------|-------| | `SERVER_PASSWORD` | `87zH26nbqT` | | `REGISTRY_PASSWORD` | `87zH26nbqT` | --- ## 🛠️ K3s Registry Configuration فایل `/etc/rancher/k3s/registries.yaml`: ```yaml mirrors: "194.5.195.53:32082": endpoint: - "http://194.5.195.53:32082" "194.5.195.53:32500": endpoint: - "http://194.5.195.53:32500" "194.5.195.53:30080": endpoint: - "http://194.5.195.53:30080" ``` --- ## 🐋 Docker-sshpass Image ایمیج سفارشی برای CI/CD که sshpass از قبل نصب داره: ```dockerfile FROM 194.5.195.53:32082/docker:latest RUN apk add --no-cache openssh-client sshpass ``` **Build و Push:** ```bash docker build -t 194.5.195.53:32082/docker-sshpass:latest . docker push 194.5.195.53:32082/docker-sshpass:latest ``` --- ## ✅ چک‌لیست آفلاین بودن - [x] ایمیج CI/CD از Nexus: `194.5.195.53:32082/docker-sshpass:latest` - [x] ایمیج dotnet/sdk از Nexus: `194.5.195.53:32082/dotnet/sdk:9.0` - [x] پکیج‌های NuGet کش شده در Nexus - [x] پکیج‌های Protobuf پابلیش به Nexus - [x] App images در registry محلی: `194.5.195.53:30080` - [x] بدون `apt-get` یا `apk add` در pipeline - [x] دیپلوی با SSH (بدون نیاز به kubeconfig خارجی) --- ## 🚨 Troubleshooting ### خطای "Permission denied" در Deploy ``` Permission denied, please try again. ``` **راه‌حل:** Secret `SERVER_PASSWORD` در Gitea تنظیم نشده. برو به: `https://git.se.kbs1.ir/admin//settings/actions/secrets` ### خطای "unauthorized" در Push ``` unauthorized: access denied ``` **راه‌حل:** Secret `REGISTRY_PASSWORD` تنظیم نشده. ### خطای Pull Image ``` failed to pull image ``` **راه‌حل:** 1. چک کن ایمیج در Nexus وجود داره 2. چک کن `insecure-registries` درست تنظیم شده --- ## 📊 وضعیت نهایی سیستم ### ✅ **سرویس‌های فعال و سالم (17 pod):** | سرویس | Namespace | وضعیت | ایمیج | |-------|-----------|--------|-------| | **gitea** | default | ✅ Running | `194.5.195.53:32082/gitea/gitea:latest` | | **gitea-runner** | default | ✅ Running | `194.5.195.53:32082/gitea/act_runner:latest` | | **nexus** | default | ✅ Running | `194.5.195.53:32082/sonatype/nexus3:3.38.0` | | **cms** | default | ✅ Running | `194.5.195.53:30080/admin/cms:latest` | | **backoffice** | default | ✅ Running | `194.5.195.53:30080/admin/backoffice:latest` | | **backoffice-bff** | default | ✅ Running | `194.5.195.53:30080/admin/backoffice-bff:latest` | | **frontoffice** | default | ✅ Running | `194.5.195.53:30080/admin/frontoffice:latest` | | **frontoffice-bff** | default | ✅ Running | `194.5.195.53:30080/admin/frontoffice-bff:latest` | | **cert-manager** | cert-manager | ✅ Running | `194.5.195.53:32082/quay.io/jetstack/cert-manager-*` | | **nginx-deploy** | default | ✅ Running | `194.5.195.53:32082/nginx:alpine` | | **mssql** | default | ✅ Running | `194.5.195.53:32082/mcr.microsoft.com/mssql/server:2022-latest` | | **coredns** | kube-system | ✅ Running | `rancher/mirrored-coredns-coredns:1.13.1` | | **metrics-server** | kube-system | ✅ Running | `rancher/mirrored-metrics-server:v0.8.0` | ### ⚠️ **مشکلات جزئی (غیرضروری):** - `netshoot` - CrashLoopBackOff (ابزار تست شبکه) - `ingress-nginx-controller` - CrashLoopBackOff (environment variables) - `local-path-provisioner` - CrashLoopBackOff (storage provisioner) --- ## 🎯 دستاوردها ### **قبل از امروز:** - ❌ اکثر سرویس‌ها از Docker Hub و registryهای خارجی ایمیج می‌کشیدن - ❌ CI/CD pipeline نیاز به اینترنت داشت برای نصب sshpass - ❌ NuGet packages از internet دانلود می‌شدن ### **بعد از امروز:** - ✅ **100% آفلاین:** تمام ایمیج‌های اصلی از Nexus کش می‌شن - ✅ **CI/CD کاملاً آفلاین:** ایمیج `docker-sshpass` آماده - ✅ **NuGet کش شده:** ~500 پکیج .NET در Nexus - ✅ **Auto-deploy:** kubectl rollout restart خودکار - ✅ **Protobuf publishing:** پکیج‌های محلی به Nexus --- ## 🔧 تنظیمات انجام شده امروز ### **1. ایمیج‌های جدید کش شده:** ```bash # K8s System Images 194.5.195.53:32082/quay.io/jetstack/cert-manager-cainjector:v1.14.0 194.5.195.53:32082/quay.io/jetstack/cert-manager-controller:v1.14.0 194.5.195.53:32082/quay.io/jetstack/cert-manager-webhook:v1.14.0 194.5.195.53:32082/registry.k8s.io/ingress-nginx/controller:v1.14.1 194.5.195.53:32082/rancher/local-path-provisioner:v0.0.32 194.5.195.53:32082/rancher/klipper-helm:v0.9.10-build20251111 194.5.195.53:32082/rancher/klipper-lb:v0.4.13 # Application Images 194.5.195.53:32082/mcr.microsoft.com/mssql/server:2022-latest 194.5.195.53:32082/nginx:alpine 194.5.195.53:32082/nginx:stable 194.5.195.53:32082/nicolaka/netshoot:latest 194.5.195.53:32082/registry:2 # CI/CD Images 194.5.195.53:32082/docker-sshpass:latest (custom-built) ``` ### **2. Deployment Updates:** همه deploymentها با `kubectl patch` آپدیت شدن تا از Nexus استفاده کنن: ```yaml # مثال: cert-manager spec: template: spec: containers: - name: cert-manager-cainjector image: 194.5.195.53:32082/quay.io/jetstack/cert-manager-cainjector:v1.14.0 ``` ### **3. CI/CD Pipeline بهبودها:** ```yaml container: image: 194.5.195.53:32082/docker-sshpass:latest # ✅ آفلاین steps: - name: Deploy to Kubernetes run: | export SSHPASS="${{ secrets.SERVER_PASSWORD }}" sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} " kubectl rollout restart deployment/ kubectl rollout status deployment/ --timeout=180s " ``` ### **4. مشکلات حل شده:** - ✅ **gitea + gitea-runner:** از Nexus images استفاده - ✅ **docker-sshpass:** ایمیج سفارشی برای CI/CD - ✅ **cert-manager:** تمام componentها آپدیت - ✅ **mssql:** EULA acceptance اضافه شد - ⚠️ **seq:** temporarily deleted (ایمیج push نشد) --- ## 🚀 دستورات مهم برای آینده ### **تست آفلاین بودن:** ```bash # چک کردن ایمیج‌های خارجی kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort | uniq | grep -v '194.5.195.53' # تست CI/CD git commit --allow-empty -m "test offline pipeline" && git push # چک rollout status kubectl rollout status deployment/ --timeout=180s ``` ### **اضافه کردن ایمیج جدید به Nexus:** ```bash # Export از containerd ctr -n k8s.io images export /tmp/image.tar # Push به Nexus skopeo copy --dest-tls-verify=false --dest-creds admin:87zH26nbqT \ docker-archive:/tmp/image.tar docker://194.5.195.53:32082/ # Update deployment kubectl patch deployment --type='merge' \ -p='{"spec":{"template":{"spec":{"containers":[{"name":"","image":"194.5.195.53:32082/"}]}}}}' ``` --- ## 📅 تاریخ آخرین به‌روزرسانی **29 ژانویه 2026** - سیستم کاملاً آفلاین شد