docs: add portable from-zero deploy runbook and GitOps templates

Document server-side rollout (values, Sealed Secrets, logging, greenfield
reset) with environment variables so any cluster can follow the same steps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
keyhan
2026-07-03 12:17:55 +03:30
parent 22359be40e
commit 6d9cd89cc5
9 changed files with 668 additions and 13 deletions
+18 -5
View File
@@ -2,6 +2,8 @@
این مستند جریان کامل Build و Deploy پلتفرم را توضیح می‌دهد: از Push شدن کد روی `main` تا استقرار خودکار روی Kubernetes.
> **استقرار از صفر روی سرور جدید:** [`RUNBOOK-DEPLOY.fa.md`](RUNBOOK-DEPLOY.fa.md) — شامل جدول متغیرها، seal کردن Secretها، logging stack، greenfield reset، و چک‌لیست سلامت.
---
## معماری و جریان کلی
@@ -26,9 +28,10 @@ flowchart TD
1. Developer روی شاخهٔ `main` در ریپوی اپلیکیشن (`git.abrban.com/abrban/cloud-host`) push می‌کند.
2. Workflow در [`.gitea/workflows/build-deploy.yaml`](.gitea/workflows/build-deploy.yaml) روی Runner با لیبل `abrban-builder` اجرا می‌شود.
3. Runner کد را با توکن CI کلون می‌کند و تگ ایمیج (`YYYYMMDD-HHMM-<sha>`) را می‌سازد.
4. برای هر ایمیج (backend و frontend) یک Kaniko Job در namespace `cloudhost-builds` ساخته می‌شود که کد را کلون، ایمیج را build و به Harbor push می‌کند.
5. بعد از موفقیت هر دو Build، همان Runner ریپوی **`cloud-host-gitops`** را کلون می‌کند، مقدار `images.backend.tag` و `images.frontend.tag` را در `platform/values-abrban.yaml` عوض و commit/push می‌کند.
6. Argo CD (Application به نام `abrban-platform` با sync خودکار) تغییر را تشخیص می‌دهد و نسخهٔ جدید را در namespace `cloudhost` مستقر می‌کند.
4. **Job تست بک‌اند** در namespace `cloudhost-builds` اجرا می‌شود (`npm ci` + `jest --ci`) — در صورت fail، بیلد ایمیج شروع نمی‌شود.
5. برای هر ایمیج (backend و frontend) یک Kaniko Job در namespace `cloudhost-builds` ساخته می‌شود که کد را کلون، ایمیج را build و به Harbor push می‌کند.
6. بعد از موفقیت هر دو Build، همان Runner ریپوی **`cloud-host-gitops`** را کلون می‌کند، مقدار `images.backend.tag` و `images.frontend.tag` را در `platform/values-abrban.yaml` عوض و commit/push می‌کند (با retry و `git pull --rebase` در صورت race).
7. Argo CD (Application به نام `abrban-platform` با sync خودکار) تغییر را تشخیص می‌دهد و نسخهٔ جدید را در namespace `cloudhost` مستقر می‌کند.
> **جلوگیری از حلقهٔ CI:** کامیتِ Pipeline به ریپوی جدا (`cloud-host-gitops`) می‌رود که هیچ Workflowای ندارد؛ بنابراین Build دوباره trigger نمی‌شود.
@@ -249,9 +252,16 @@ git push origin main
| `gitea-act-runner-token` | `gitea` | توکن ثبت Runner |
| `kaniko-harbor-auth` | `cloudhost-builds` | dockerconfig کاربر `harbor_registry_user` |
| `gitea-gitops-repo-creds` | `argocd` | repo credential ریپوی gitops (کاربر `ci`) |
| `abrban-platform-secrets` | `cloudhost` | postgres-password، jwt-secret، jwt-refresh-secret، **cluster-kubeconfig-key** |
| `abrban-platform-secrets` | `cloudhost` | postgres-password، jwt-secret، jwt-refresh-secret، **cluster-kubeconfig-key**، **redis-password** |
| `elasticsearch-credentials` | `logging` | ELASTIC_PASSWORD، FLUENTBIT_PASSWORD (خارج از چارت پلتفرم — [`elasticsearch-credentials.example.yaml`](gitops/sealed-secrets/elasticsearch-credentials.example.yaml)) |
چارت Helm با `secrets.existingSecret: abrban-platform-secrets` در `platform/values-abrban.yaml` (ریپوی gitops) از Secret ازپیش‌ساخته استفاده می‌کند — Argo CD با `helm template` نمی‌تواند Secret تصادفی بسازد (lookup خالی است و هر sync مقادیر JWT را عوض می‌کند).
چارت Helm با `secrets.existingSecret: abrban-platform-secrets` در `platform/values-abrban.yaml` (ریپوی gitops) از Secret ازپیش‌ساخته استفاده می‌کند — Argo CD با `helm template` نمی‌تواند Secret تصادفی بسازد (lookup خالی است و هر sync مقادیر JWT/Redis را عوض می‌کند).
نمونهٔ کامل values: [`gitops/platform/values-abrban.example.yaml`](gitops/platform/values-abrban.example.yaml) — شامل mirror ایمیج postgres/redis، `BASE_IMAGE_REGISTRY`، و envهای Elastic.
### Greenfield / ارتقا از نسخهٔ قدیم
اگر کلاستر قبلاً با schema یا namespace قدیمی بالا آمده، قبل از deploy جدید **reset دیتابیس** لازم است. مراحل کامل (با متغیرهای قابل‌تنظیم برای هر محیط) در **[`RUNBOOK-DEPLOY.fa.md` — فاز ۶](RUNBOOK-DEPLOY.fa.md#فاز-۶--greenfield--ارتقا-از-نسخهٔ-قدیم)**.
### ساخت/به‌روزرسانی یک SealedSecret
@@ -305,4 +315,7 @@ Secretهایی که هنوز دستی‌اند (خارج از چرخهٔ CI): `a
| دیدن تگ‌های موجود در registry | از داخل کلاستر: `wget -qO- "http://harbor_registry_user:<REG_PASS>@harbor-registry.cloudhost.svc.cluster.local:5000/v2/abrban/cloudhost-backend/tags/list"` |
| Backend CrashLoop — CLUSTER_KUBECONFIG_KEY | Secret `abrban-platform-secrets` باید کلید `cluster-kubeconfig-key` داشته باشد و در values: `secrets.existingSecret: abrban-platform-secrets` |
| Backend CrashLoop — DB auth | پسورد postgres در Secret با DB واقعی هم‌خوان باشد (`ALTER USER ... WITH PASSWORD` در صورت rotate شدن Secret) |
| Backend CrashLoop — Redis auth | Secret `abrban-platform-secrets` باید کلید `redis-password` داشته باشد؛ backend و Redis پلتفرم هر دو از آن استفاده می‌کنند |
| Backend CrashLoop — ELASTIC_PASSWORD | در production مقدار پیش‌فرض رد می‌شود — env در values-abrban.yaml باید رمز rotate‌شده داشته باشد |
| Workflow fail — tests | Job `test-be-*` در ns `cloudhost-builds``kubectl logs job/... -c test` |
| SealedSecret باز نمی‌شود | `kubectl get sealedsecrets -A` (ستون SYNCED) و لاگ `kubectl -n kube-system logs deploy/sealed-secrets-controller` |