14 KiB
14 KiB
🚀 راهنمای دیپلوی آفلاین 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 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 (یکسان برای همه پروژهها)
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:
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 از قبل نصب داره:
FROM 194.5.195.53:32082/docker:latest
RUN apk add --no-cache openssh-client sshpass
Build و Push:
docker build -t 194.5.195.53:32082/docker-sshpass:latest .
docker push 194.5.195.53:32082/docker-sshpass:latest
✅ چکلیست آفلاین بودن
- ایمیج CI/CD از Nexus:
194.5.195.53:32082/docker-sshpass:latest - ایمیج dotnet/sdk از Nexus:
194.5.195.53:32082/dotnet/sdk:9.0 - پکیجهای NuGet کش شده در Nexus
- پکیجهای Protobuf پابلیش به Nexus
- App images در registry محلی:
194.5.195.53:30080 - بدون
apt-getیاapk addدر pipeline - دیپلوی با 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
راهحل:
- چک کن ایمیج در Nexus وجود داره
- چک کن
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. ایمیجهای جدید کش شده:
# 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 استفاده کنن:
# مثال: 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 بهبودها:
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 نشد)
🚀 دستورات مهم برای آینده
تست آفلاین بودن:
# چک کردن ایمیجهای خارجی
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:
# 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 - سیستم کاملاً آفلاین شد