Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
# 🚀 راهنمای دیپلوی آفلاین 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
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="FourSat-Offline" value="http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 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/<project-name>
|
||||
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/<repo>.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/<deployment-name>
|
||||
kubectl rollout status deployment/<deployment-name> --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/<repo>/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/<repo>/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/<app>
|
||||
kubectl rollout status deployment/<app> --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/<app> --timeout=180s
|
||||
```
|
||||
|
||||
### **اضافه کردن ایمیج جدید به Nexus:**
|
||||
```bash
|
||||
# Export از containerd
|
||||
ctr -n k8s.io images export /tmp/image.tar <image-name>
|
||||
|
||||
# Push به Nexus
|
||||
skopeo copy --dest-tls-verify=false --dest-creds admin:87zH26nbqT \
|
||||
docker-archive:/tmp/image.tar docker://194.5.195.53:32082/<image-path>
|
||||
|
||||
# Update deployment
|
||||
kubectl patch deployment <name> --type='merge' \
|
||||
-p='{"spec":{"template":{"spec":{"containers":[{"name":"<container>","image":"194.5.195.53:32082/<image>"}]}}}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 تاریخ آخرین بهروزرسانی
|
||||
**29 ژانویه 2026** - سیستم کاملاً آفلاین شد
|
||||
Reference in New Issue
Block a user