c78850f86e
BUSINESS-02: - فرمول هایبرید: حذف MIN، اضافه validation کیفپول اعتباری - فلوی خرید: اضافه مرحله بررسی موجودی + UserWalletChangeLog - نامگذاری جدید کیفپولها: اصلی، اعتباری، پاداش تیمی - جدول وضعیت: اضافه WalletChangeLog + Validation BUSINESS-03: - بخش ۹ جدید: ExpirePendingOrdersService (۱۵ دقیقه) - دیاگرام Mermaid فلوی انقضا TECH-03: - فیکس URL پروداکشن (kbs1→kbs2) + هشدار - ۴ کامیت جدید در بخش ۹.۲ - بخش ۹.۳ فیکس URL پروداکشن - بخش ۹.۴ نامگذاری کیفپولها
541 lines
18 KiB
Markdown
541 lines
18 KiB
Markdown
# 🚀 استقرار، CI/CD و زیرساخت
|
||
|
||
> **منابع ادغامشده:** `CICD-PIPELINE-GUIDE.md`, `DEPLOYMENT-README.md`, `INFRASTRUCTURE-GUIDE.md`, `INGRESS-NGINX-WARNING.md`, `OFFLINE-DEPLOYMENT-GUIDE.md`, `SERVER-MIRRORS-CONFIG.md`
|
||
> **آخرین بروزرسانی:** اسفند ۱۴۰۴ (بروزرسانی: فیکس URL پروداکشن + چریپیک فیکسهای WalletChangeLog/Validation/Expiry)
|
||
|
||
---
|
||
|
||
## ۱. سرورها
|
||
|
||
| سرور | 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 ساختار
|
||
|
||
مانیفستهای K8s **داخل ریپوی CMS** نگهداری میشن و توسط CI/CD اعمال میشن:
|
||
|
||
```
|
||
CMS/
|
||
k8s/
|
||
staging/
|
||
cms-config.yaml ← K8s Secret (appsettings.Staging.json)
|
||
cms-deployment.yaml ← PVC + Deployment + Service + Ingress
|
||
production/
|
||
cms-config.yaml ← K8s Secret (appsettings.Production.json)
|
||
cms-deployment.yaml ← PVC + Deployment + Service + Ingress
|
||
```
|
||
|
||
> ⚠️ **هر دو محیط از namespace `default` استفاده میکنن.**
|
||
|
||
### ۳.۲ PersistentVolume برای آپلود فایل
|
||
|
||
فایلهای آپلودشده (عکس محصولات، بلاگ، آواتار و ...) در `/app/Uploads` ذخیره میشن.
|
||
برای جلوگیری از حذف فایلها با ریستارت Pod، یک **PersistentVolumeClaim** مونت شده:
|
||
|
||
```yaml
|
||
# PVC — 20Gi ذخیرهسازی دائمی
|
||
apiVersion: v1
|
||
kind: PersistentVolumeClaim
|
||
metadata:
|
||
name: cms-uploads-pvc
|
||
namespace: default
|
||
spec:
|
||
accessModes: [ReadWriteOnce]
|
||
resources:
|
||
requests:
|
||
storage: 20Gi
|
||
```
|
||
|
||
```yaml
|
||
# Volume Mount در Deployment
|
||
volumeMounts:
|
||
- name: cms-uploads
|
||
mountPath: /app/Uploads
|
||
volumes:
|
||
- name: cms-uploads
|
||
persistentVolumeClaim:
|
||
claimName: cms-uploads-pvc
|
||
```
|
||
|
||
| تنظیم | مقدار |
|
||
|--------|-------|
|
||
| **PVC Name** | `cms-uploads-pvc` |
|
||
| **Mount Path** | `/app/Uploads` |
|
||
| **Access Mode** | `ReadWriteOnce` |
|
||
| **حجم** | `20Gi` |
|
||
| **StorageClass** | `local-path` (K3s default) |
|
||
| **Replicas** | `1` (محدودیت RWO) |
|
||
|
||
> 💡 **نکته مهم:** چون `ReadWriteOnce` هست، فقط **1 replica** میتونه بنویسه. برای 2+ replica نیاز به NFS/CephFS با `ReadWriteMany` هست.
|
||
|
||
### ۳.۳ تنظیمات محیطی (K8s Secret)
|
||
|
||
تنظیمات حساس (ConnectionString, Email, SMS, ZarinPal) **در K8s Secret** نگهداری میشن — نه داخل Docker image.
|
||
فایل `appsettings.{Environment}.json` از Secret به `/app/` مونت میشه و .NET اون رو override میخونه.
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
S["K8s Secret<br/>cms-appsettings"] -->|volumeMount| F["/app/appsettings.*.json"]
|
||
F --> D[".NET reads config"]
|
||
I["Docker Image<br/>appsettings.json (base)"] --> D
|
||
```
|
||
|
||
| محیط | `ASPNETCORE_ENVIRONMENT` | فایل Config (از Secret) |
|
||
|------|---------------------------|-------------|
|
||
| **Staging** | `Staging` | `appsettings.Staging.json` |
|
||
| **Production** | `Production` | `appsettings.Production.json` |
|
||
|
||
**Secret manifest** (`cms-config.yaml`):
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: cms-appsettings
|
||
namespace: default
|
||
type: Opaque
|
||
stringData:
|
||
appsettings.Staging.json: | # یا appsettings.Production.json
|
||
{ "ConnectionStrings": { ... }, "ZarinPal": { ... }, ... }
|
||
```
|
||
|
||
**Volume mount در Deployment:**
|
||
```yaml
|
||
volumeMounts:
|
||
- name: cms-config
|
||
mountPath: /app/appsettings.Staging.json
|
||
subPath: appsettings.Staging.json
|
||
readOnly: true
|
||
volumes:
|
||
- name: cms-config
|
||
secret:
|
||
secretName: cms-appsettings
|
||
```
|
||
|
||
env varهای K8s manifest (فقط environment و URL):
|
||
```yaml
|
||
env:
|
||
- name: ASPNETCORE_ENVIRONMENT
|
||
value: "Staging" # یا "Production"
|
||
- name: ASPNETCORE_URLS
|
||
value: "http://+:8080"
|
||
```
|
||
|
||
> 💡 **تغییر config بدون deploy:** `kubectl edit secret cms-appsettings && kubectl rollout restart deployment/cms`
|
||
|
||
### ۳.۴ مثال Deployment (واقعی)
|
||
|
||
```yaml
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: cms
|
||
namespace: default
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: cms
|
||
template:
|
||
spec:
|
||
containers:
|
||
- name: cms
|
||
image: 194.5.195.53:30080/admin/cms:latest
|
||
imagePullPolicy: Always
|
||
ports:
|
||
- containerPort: 8080
|
||
env:
|
||
- name: ASPNETCORE_ENVIRONMENT
|
||
value: "Staging"
|
||
- name: ASPNETCORE_URLS
|
||
value: "http://+:8080"
|
||
volumeMounts:
|
||
- name: cms-uploads
|
||
mountPath: /app/Uploads
|
||
- name: cms-config
|
||
mountPath: /app/appsettings.Staging.json
|
||
subPath: appsettings.Staging.json
|
||
readOnly: true
|
||
resources:
|
||
requests: { memory: "512Mi", cpu: "500m" }
|
||
limits: { memory: "1Gi", cpu: "1000m" }
|
||
volumes:
|
||
- name: cms-uploads
|
||
persistentVolumeClaim:
|
||
claimName: cms-uploads-pvc
|
||
- name: cms-config
|
||
secret:
|
||
secretName: cms-appsettings
|
||
```
|
||
|
||
### ۳.۵ Ingress
|
||
|
||
**Staging:**
|
||
```yaml
|
||
spec:
|
||
ingressClassName: nginx
|
||
rules:
|
||
- host: cms.se.kbs1.ir
|
||
```
|
||
|
||
**Production:**
|
||
```yaml
|
||
spec:
|
||
ingressClassName: nginx
|
||
tls:
|
||
- hosts: [cms.kbs1.ir, cms.kbs2.ir]
|
||
secretName: cms-tls
|
||
rules:
|
||
- host: cms.kbs2.ir
|
||
- host: cms.kbs1.ir
|
||
```
|
||
|
||
> ⚠️ **هشدار:** از `spec.ingressClassName: nginx` استفاده کنید، نه `kubernetes.io/ingress.class` annotation (deprecated).
|
||
|
||
### ۳.۶ جداسازی appsettings در Git
|
||
|
||
هر برنچ فقط فایل config مربوط به محیط خودش رو داره:
|
||
|
||
| برنچ | `appsettings.json` | `appsettings.Staging.json` | `appsettings.Production.json` |
|
||
|------|---|---|---|
|
||
| `kub-stage` | ✅ | ✅ | ❌ حذف شده |
|
||
| `production` | ✅ | ❌ حذف شده | ✅ |
|
||
|
||
**چرا؟** چون config اصلی از K8s Secret میاد (`cms-config.yaml`)، فایلهای محیط دیگه داخل ایمیج اضافی و گمراهکنندهان.
|
||
همچنین وقتی merge/cherry-pick میکنید، فایل config محیط دیگه دیگه conflict ایجاد نمیکنه.
|
||
|
||
> ⚠️ **کامیتهای حذف فایل config رو هرگز cherry-pick نکنید به برنچ دیگه!**
|
||
> `e72673c` (حذف Production از staging) و `3ebe0f9` (حذف Staging از production)
|
||
|
||
### ۳.۷ خلاصه: چه چیزهایی دائمی هستند (مستقل از ایمیج)
|
||
|
||
| چه چیزی | مکانیزم K8s | محل Mount |
|
||
|---------|-------------|------------|
|
||
| **فایلهای آپلود** (عکس، آواتار، ...) | `PersistentVolumeClaim` | `/app/Uploads` |
|
||
| **تنظیمات اپلیکیشن** (DB, SMS, IPG, ...) | `Secret` (`cms-appsettings`) | `/app/appsettings.{Env}.json` |
|
||
|
||
---
|
||
|
||
## ۴. CI/CD Pipeline
|
||
|
||
### ۴.۱ Gitea Actions Workflows (CMS)
|
||
|
||
فایلهای پایپلاین:
|
||
```
|
||
CMS/.gitea/workflows/
|
||
├── kub-deploy.yml ← Staging (branch: kub-stage)
|
||
├── prod-deploy.yml ← Production (branch: production)
|
||
└── cms-stage.yml ← قدیمی (IIS روی Windows — غیرفعال)
|
||
```
|
||
|
||
### ۴.۲ فلوی Staging (`kub-deploy.yml`)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["Push to kub-stage"] --> B["Start Docker daemon"]
|
||
B --> C["Clone repo"]
|
||
C --> D["Pack & Push Proto NuGet"]
|
||
D --> E["Docker build → tag :latest"]
|
||
E --> F["Push to 194.5.195.53:30080"]
|
||
F --> G["SCP cms-config.yaml + cms-deployment.yaml"]
|
||
G --> H["kubectl apply -f cms-config.yaml (Secret)"]
|
||
H --> I["kubectl apply -f cms-deployment.yaml"]
|
||
I --> J["kubectl rollout restart"]
|
||
J --> K["✅ Deployed to Staging"]
|
||
```
|
||
|
||
### ۴.۳ فلوی Production (`prod-deploy.yml`)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["Push to production"] --> B["Start Docker daemon"]
|
||
B --> C["Clone repo"]
|
||
C --> D["Pack & Push Proto NuGet"]
|
||
D --> E["Docker build → tag :sha + :prod"]
|
||
E --> F["Push to 194.5.195.53:30080"]
|
||
F --> G["SCP cms-config.yaml + cms-deployment.yaml"]
|
||
G --> H["kubectl apply -f cms-config.yaml (Secret)"]
|
||
H --> I["kubectl apply -f cms-deployment.yaml"]
|
||
I --> J["kubectl set image → sha"]
|
||
J --> K["✅ Deployed to Production"]
|
||
```
|
||
|
||
### ۴.۴ شاخهها و محیطها
|
||
|
||
| شاخه | محیط | سرور | Image Tag | Deploy |
|
||
|------|------|------|-----------|--------|
|
||
| `kub-stage` | Staging | 194.5.195.53 | `:latest` | Auto |
|
||
| `production` | Production | 45.149.79.127 | `:sha` + `:prod` | Auto |
|
||
|
||
### ۴.۵ نکات مهم CI/CD
|
||
|
||
- **Proto NuGet:** هر deploy ابتدا proto packages رو build و به Nexus push میکنه
|
||
- **Manifest apply:** پایپلاین ابتدا `cms-config.yaml` (Secret) رو apply میکنه، بعد `cms-deployment.yaml`
|
||
→ Secret + PVC + Deployment + Service + Ingress هر بار اعمال میشه
|
||
- **Image registry:** `194.5.195.53:30080` (داخلی Nexus) — نه `git.se.kbs1.ir`
|
||
- **Config دائمی:** تنظیمات در K8s Secret هست، نه داخل Docker image — تغییر config بدون rebuild ایمیج ممکنه
|
||
- **جداسازی برنچ:** هر برنچ فقط appsettings محیط خودش رو داره (بخش ۳.۶)
|
||
|
||
---
|
||
|
||
## ۵. استقرار آفلاین (Offline Deployment)
|
||
|
||
### ۵.۱ فلوی آمادهسازی
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
subgraph ONLINE["🌐 سرور اینترنتدار"]
|
||
A1["pull-base-images.sh\nدانلود Docker images"] --> A2["cache-nuget-packages.sh\nدانلود NuGet packages"]
|
||
A2 --> A3["save-images.sh\nذخیره تصاویر به tar"]
|
||
A3 --> A4["بستهبندی"]
|
||
end
|
||
|
||
A4 -->|"💾 انتقال فیزیکی\nUSB / HDD"| B1
|
||
|
||
subgraph OFFLINE["🔒 سرور آفلاین"]
|
||
B1["load-images.sh\nبارگذاری تصاویر"] --> B2["setup-nexus-complete.sh\nراهاندازی Nexus"]
|
||
B2 --> B3["build-all-offline.sh\nبیلد با Nexus محلی"]
|
||
B3 --> B4["k8s-deploy.sh\nاستقرار در K8s"]
|
||
end
|
||
```
|
||
|
||
### ۵.۲ اسکریپتهای کلیدی
|
||
|
||
| اسکریپت | کاربرد |
|
||
|----------|--------|
|
||
| `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
|
||
|
||
### ۶.۱ نقش
|
||
|
||
```mermaid
|
||
graph TD
|
||
NEXUS["Nexus داخلی"] --> NP["NuGet proxy\ncache nuget.org"]
|
||
NEXUS --> NH["NuGet hosted\nبستههای proto داخلی"]
|
||
NEXUS --> DP["Docker proxy\ncache Docker Hub"]
|
||
NEXUS --> DH["Docker hosted\nتصاویر داخلی FourSat"]
|
||
```
|
||
|
||
### ۶.۲ NuGet.config
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<configuration>
|
||
<packageSources>
|
||
<add key="nexus" value="http://localhost:8081/repository/nuget-group/index.json" />
|
||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||
</packageSources>
|
||
</configuration>
|
||
```
|
||
|
||
---
|
||
|
||
## ۷. 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)
|
||
|
||
### ۸.۱ فلوی بستهبندی
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["CMS/src/Protos/*.proto"] --> B["pack-protos.sh\ndotnet pack → .nupkg"]
|
||
B --> C["Push to BaGet / Nexus"]
|
||
C --> D["BackOffice + FrontOffice\ndotnet restore → مصرف proto"]
|
||
```
|
||
|
||
### ۸.۲ نام بسته
|
||
|
||
```xml
|
||
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="1.0.x" />
|
||
```
|
||
|
||
---
|
||
|
||
## ۹. مانیتورینگ و Health Check
|
||
|
||
### ۹.۱ مرج پروداکشن (اسفند ۱۴۰۴)
|
||
|
||
| ریپو | شاخه مبدأ | commit | نکات |
|
||
|------|------------|--------|------|
|
||
| **CMS** | `kub-stage` → `production` | `eb1b249` | حل conflict در `appsettings.Production.json` + حذف migration تکراری `u21` |
|
||
| **FrontOffice** | `kub-stage` → `production` | `f02d082` | 21 فایل، 400 insertion + فیکس GwUrl به `cms.kbs2.ir` |
|
||
| **BackOffice** | `kub-stage` → `production` | `bdea2e8` | 36 فایل، بدون conflict |
|
||
|
||
### ۹.۲ کامیتهای PVC و اصلاحات K8s (تیر ۱۴۰۴)
|
||
|
||
| commit | شرح |
|
||
|--------|------|
|
||
| `3153fd8` | feat: add PersistentVolume for CMS uploads + apply manifests in CI/CD |
|
||
| `68da3f4` | fix: staging uses namespace default, not foursat |
|
||
| `e41747a` | fix: production ingress — add cms.kbs2.ir, use ingressClassName |
|
||
| `2d6c95e` | fix: use local registry 194.5.195.53:30080 instead of git.se.kbs1.ir |
|
||
| `f8dc4ab` | fix: staging ASPNETCORE_ENVIRONMENT=Staging, remove secretKeyRef |
|
||
| `de83c31` | fix: production uses namespace default + remove foursat namespace references |
|
||
| `9288d06` | feat: externalize appsettings to K8s Secret — config persists independently |
|
||
| `e72673c` | chore(staging): remove appsettings.Production.json (فقط kub-stage) |
|
||
| `3ebe0f9` | chore(production): remove appsettings.Staging.json (فقط production) |
|
||
| `f3ac5ad` | fix: add missing UserWalletChangeLog for discount shop purchases |
|
||
| `0457ef6` | fix: validate discount wallet balance before applying discount |
|
||
| `e206b71` | fix: reduce discount order expiry from 30 to 15 minutes |
|
||
| `2620a24` | fix: correct production URLs from kbs1 to kbs2 in cms-config |
|
||
|
||
> کامیتهای PVC و Secret به هر دو شاخه push شدهاند.
|
||
> ⚠️ کامیتهای حذف appsettings فقط به برنچ مربوطه push شده — cherry-pick نکنید!
|
||
|
||
### ۹.۳ فیکس URL پروداکشن (اسفند ۱۴۰۴)
|
||
|
||
> **مشکل:** در `cms-config.yaml` پروداکشن، URLها به اشتباه `kbs1.ir` (استیج) بودند.
|
||
> زرینپال callback را به سرور استیج میفرستاد → خطای 401 → `Code=-1` (خطای ناشناخته).
|
||
|
||
| فیلد | مقدار اشتباه | مقدار صحیح |
|
||
|------|-------------|------------|
|
||
| `CmsBaseUrl` | `https://cms.kbs1.ir` | `https://cms.kbs2.ir` |
|
||
| `FrontOfficeBaseUrl` | `https://kbs1.ir` | `https://kbs2.ir` |
|
||
|
||
```bash
|
||
# فیکس مستقیم روی سرور (بدون نیاز به rebuild)
|
||
kubectl apply -f cms-config.yaml
|
||
kubectl rollout restart deployment/cms
|
||
```
|
||
|
||
### ۹.۴ نامگذاری کیفپولها (اسفند ۱۴۰۴)
|
||
|
||
> تغییر عنوان کیفپولها در تمام UI (FrontOffice: 5 فایل، BackOffice: 7 فایل):
|
||
|
||
| فیلد | نام قدیم | نام جدید |
|
||
|------|---------|----------|
|
||
| `Balance` | عادی / نقدی | **کیف پول اصلی** |
|
||
| `DiscountBalance` | تخفیفی / تخفیف | **کیف پول اعتباری** |
|
||
| `NetworkBalance` | شبکه / طلایی | **پاداش تیمی** |
|
||
|
||
**تنظیمات محیطی Production (`appsettings.Production.json`):**
|
||
|
||
| تنظیم | مقدار |
|
||
|--------|-------|
|
||
| `ZarinPal.MerchantId` | `4225d555-5fa9-4df0-9b61-1ce152cbbba8` |
|
||
| `ZarinPal.UseSandbox` | `false` |
|
||
| `CmsBaseUrl` | `https://cms.kbs2.ir` |
|
||
| `FrontOfficeBaseUrl` | `https://kbs2.ir` |
|
||
| `SeedWorkers.MagicWalletCycleSeed.Enabled` | `true` |
|
||
| `Kestrel.Endpoints.Grpc.Protocols` | `Http2` |
|
||
| `Seq.ServerUrl` | `http://seq-svc:5341` |
|
||
| `ConnectionStrings.Default` | `Server=mssql-svc;Database=KBS` |
|
||
|
||
> ⚠️ **مهم:** URLها باید `kbs2.ir` باشند نه `kbs1.ir` — اشتباه در URL باعث خطای 401 زرینپال میشود.
|
||
|
||
```bash
|
||
# k8s-health-check.sh (namespace = default)
|
||
kubectl get pods
|
||
kubectl top pods
|
||
kubectl logs deployment/cms --tail=50
|
||
|
||
# بررسی PVC
|
||
kubectl get pvc cms-uploads-pvc
|
||
kubectl exec deployment/cms -- ls /app/Uploads | wc -l
|
||
|
||
# تست سرویسها
|
||
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
|
||
```
|