باگها، ریسکهای پروداکشن و موارد بهبود — بیلد، دیتابیسها، GitOps/CI-CD و امنیت اپلیکیشن
پروژه معماری خوبی دارد اما در وضعیت فعلی آماده پروداکشن نیست. چند دسته مشکل بحرانی وجود دارد که یا هماکنون باگ هستند یا حتماً در پروداکشن (بهویژه در شبکه ایران) میشکنند:
helm upgrade قطعاً میشکند.backend/src/build/build.service.ts:1311-1314 — دستور COPY ... 2>/dev/null || true از ریدایرکت شل پشتیبانی نمیکند؛ Kaniko این خطوط را رد میکند و بیلد هر اپ Go شکست میخورد.
backend/src/build/build.service.ts:1034 — RUN npm run build || echo "..."؛ اگر بیلد خطا بدهد باز هم ایمیج ساخته میشود و اپ خراب دیپلوی میشود. کاربر «بیلد موفق» میبیند ولی اپ کار نمیکند.
همه رانتایمها (node:, php:, python:, golang:, wordpress:) و ایمیج Kaniko و init pods (alpine:3.19, alpine/git) مستقیم از رجیستریهای عمومی pull میشوند. آینه فقط برای استک لاگینگ تعریف شده (configuration.ts:151). در ایران بیشترین منبع شکست بیلد است.
backend/src/build/build.service.ts:1085 — فقط pdo, pdo_mysql, opcache نصب میشود؛ mbstring, xml, bcmath, zip, fileinfo, tokenizer که Laravel استاندارد لازم دارد نصب نمیشود.
backend/src/build/build.service.ts:1413 — تشخیصدهنده pyproject.toml را Python میشناسد ولی Dockerfile فقط requirements.txt نصب میکند؛ پروژههای Poetry/PDM فقط Flask+gunicorn پیشفرض میگیرند. اگر install خطا بدهد، fallback خاموش (2>/dev/null ||) اپ اشتباه بالا میآورد.
build.service.ts:588 بیلد Next.js/.NET/Composer اغلب بیشتر میخواهد → OOMKilled. build.service.ts:775 PVC بیلد storageClassName ندارد → در کلاستر بدون SC پیشفرض برای همیشه Pending میماند. همچنین npm install --legacy-peer-deps بهجای npm ci (خط ۱۰۱۸).
build.service.ts:498-523 — cloneUrl با توکن embedشده در command کانتینر → قابل دیدن در kubectl get pod -o yaml، etcd و audit log. همچنین ${branch} بدون کوت داخل شل → نامی مثل main; curl evil کد اجرا میکند. بدون اعتبارسنجی URL گیت (SSRF به IPهای داخلی کلاستر). خطر Zip slip / zip bomb در استخراج با unzip (خط ۴۶۲) با سقف آپلود ۱۰GiB.
build.service.ts:56 — state بیلد در Map حافظه است؛ بعد از ریاستارت، Job روی کلاستر ادامه میدهد ولی deployment در وضعیت BUILDING گیر میکند و reconcile نمیشود. همچنین دیپلوی همزمان برای یک اپ قفل ندارد و روی همان Helm release رقابت میکنند.
پیشنمایش با ساخت یک عدد ۷ رقمی پایدار برای هر اپ و host بهشکل {userPrefix}-{previewNumber}.{previewRootDomain} کار میکند.
kubernetes.service.ts:291 — حتی قبل از تأیید DNS؛ کاربر تا وریفای شدن دامنه هیچ آدرس قابلدسترسی ندارد. پیشنمایش نیازمند DNS wildcard فعال + cert-manager و مقدار PREVIEW_BASE_DOMAIN است.
kubernetes.service.ts:2955 — عارضه جانبی که ممکن است اپ را ناخواسته روی IP نود باز کند.
deployments.service.ts:360 — ایمیج روی رجیستری کلاستر A ساخته و push میشود، ولی deployWithClusterFallback میتواند روی کلاستر B دیپلوی کند که آن ایمیج را ندارد.
redis-deployment.yaml:18، rabbitmq-deployment.yaml:19 — randAlphaNum 16 بدون lookup هر بار مقدار جدید تولید میکند؛ resource-policy: keep فقط جلوی حذف را میگیرد نه تغییر. بعد از هر redeploy رمز عوض میشود ولی داده PVC رمز قدیمی دارد → قطع اتصال. الگوی درست در چارت پلتفرم (cloudhost-platform/templates/secret.yaml) با lookup موجود است.
redis-deployment.yaml:80 — redis-cli ping بدون -a؛ با --requirepass جواب NOAUTH → probe رد → CrashLoopBackOff. همین برای probe مونگو بدون credential.
kubernetes.service.ts:4389 — export/restore فقط Postgres و MySQL دارد؛ اپ Mongo dump خراب میگیرد. kubernetes.service.ts:4724 — restore محتوای wp-content از طریق Secret ذخیره میشود که محدودیت ~۱MiB دارد؛ هر wp-content واقعی بزرگتر است → شکست.
ایمیج رسمی وردپرس فقط MySQL/MariaDB را میشناسد ولی پلتفرم databaseType: postgresql یا حتی none را میپذیرد → سایت بالا نمیآید. باید هنگام رانتایم WordPress دیتابیس اجباراً MySQL شود.
postgres:16-alpine, mysql:8.0, ...)؛ override database.image هست ولی backend هرگز آن را ست نمیکند.strategy: Recreate برای دیتابیس/Redis/RabbitMQ → در آپگرید ایمیج پاد جدید منتظر ولوم میماند.dbPassword خالی باشد هر دیپلوی رمز جدید میسازد و با داده قدیمی PVC ناسازگار میشود.suspend هم گرنتهای NodePort را باطل نمیکند.migrations-job.yaml:50-53 — Job همه فایلهای SQL را در هر اجرا دوباره اجرا میکند بدون جدول ردیابی نسخه. 001_service_access_grants.sql:2,9 از CREATE TYPE بدون گارد استفاده میکند → آپگرید دوم: ERROR: type already exists → sync fail.
migrations-job.yaml:10-11 — post-upgrade؛ backend جدید ممکن است قبل از آماده شدن اسکیما بالا بیاید → CrashLoop. باید pre-upgrade باشد.
هیچ SQL جدولهای users/applications را نمیسازد؛ روی دیتابیس خالی اولین migration شکست میخورد. 015_application_product_type.sql:5-6 ستون user_id میسازد ولی entity آن را userId تعریف کرده (application.entity.ts:150) → ساخت ایندکس fail.
backend/k8s/logging/elasticsearch-stack.yaml:21-23 — ELASTIC_PASSWORD: "CloudHost2024!Secure" و FLUENTBIT_PASSWORD. باید rotate و از گیت خارج شوند. همینها بهعنوان default در configuration.ts:148-150 هستند و در validate-production بررسی نمیشوند.
git push بدون pull --rebase (workflow:177) → احتمال half-done deploy.strategy: Recreate روی backend (backend-deployment.yaml:12) → داونتایم کامل API در هر دیپلوی.requirepass؛ backup پستگرس خاموش.docker compose up --build کامل کار نمیکند — backend با NODE_ENV=production → synchronize:false و بدون migration → جدولها موجود نیست.billing-wallet.controller.ts:45-49 — POST /billing/wallet/charge بدون درگاه پرداخت مستقیم chargeWallet را صدا میزند → پول رایگان در پروداکشن. همچنین gateway/verify با PAYMENT_GATEWAY_STUB_ENABLED=true مبلغ دلخواه را میپذیرد.
deployments.service.ts:637 startDeployment اپ suspendشده را بدون بررسی وضعیت/کیف پول resume میکند. triggerDeployment (دیپلوی اول) گارد بیلینگ ندارد. applications.controller.ts:375 PATCH resources ارتقا را بدون مسیر پرداخت انجام میدهد.
kubernetes.service.ts:2687-2689 — user-${userId.split('-')[0]}؛ دو کاربر با ۸ کاراکتر اول یکسان namespace مشترک و دسترسی به workload/secret همدیگر میگیرند. همین مشکل در ایزولهسازی لاگ الستیک (elasticsearch.service.ts:676).
gitToken و dbPassword در پاسخ API برمیگردند (application.entity.ts:54,114) — نیاز به @Exclude.localStorage (frontend/src/lib/store.ts:43) → در معرض XSS.Math.random() بهجای CSPRNG (verification.service.ts:188) و race در مصرف OTP (خط ۲۲۵).default-jwt-secret).POST /billing/wallet/charge پشت درگاه پرداخت واقعی.triggerDeployment، startDeployment و PATCH resources.pre-upgrade + base schema برای نصب تازه.015 (user_id → userId) و گارد duplicate_object برای CREATE TYPE در 001.COPY در Dockerfile گو و حذف || echo از بیلد Node.| اولویت | اقدام |
|---|---|
| ۹ | الگوی lookup برای رمز Redis/RabbitMQ (توقف چرخش رمز). |
| ۱۰ | probe رِدیس/مونگو با احراز هویت. |
| ۱۱ | آینهکردن base imageهای بیلد + ایمیج دیتابیسها برای شبکه ایران. |
| ۱۲ | transaction/lock روی عملیات کیف پول. |
| ۱۳ | strategy: Recreate روی سرویسهای stateful و RollingUpdate روی backend. |
| ۱۴ | رفع ImagePullBackOff در fallback بینکلاستری. |
| ۱۵ | حذف gitToken/dbPassword از پاسخها با @Exclude. |
| ۱۶ | اعتبارسنجی و کوت gitBranch، انتقال توکن گیت به Secret. |
| ۱۷ | پشتیبانی MongoDB در snapshot، restore وردپرس از PVC بهجای Secret. |
| ۱۸ | اجبار MySQL برای رانتایم WordPress. |
| ۱۹ | اجرای تست در مسیر Gitea قبل از دیپلوی. |
| ۲۰ | resource limits و backup پستگرس روی کنترلپلین. |