# ๐Ÿ—๏ธ CloudHost PaaS โ€” System Architecture ## Overview CloudHost is a self-service PaaS that lets users deploy applications onto Kubernetes clusters managed by a super admin. Source code (uploaded archive or git repo) is turned into a container image **inside the cluster** with Kaniko, then rolled out via Helm. It includes a full billing/wallet system, automated lifecycle management, managed databases/services, Elasticsearch-backed logging, and a bilingual (Persian/English) panel. Supported runtimes โ€” each built from a platform-maintained `Dockerfile` template: **Node.js, Laravel, Go, PHP, Python, Django, .NET**, and **WordPress** (official image). --- ## ๐Ÿงฑ High-Level Architecture ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ USERS / ADMINS (Browser) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ HTTPS โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ FRONTEND โ€” Next.js 16 (App Router, bilingual) โ”‚ โ”‚ Landing โ”‚ Auth (OTP) โ”‚ Deploy Wizard โ”‚ Dashboard โ”‚ Admin Panel โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ REST /api/v1 (JSON) โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ BACKEND โ€” NestJS 11 โ”‚ โ”‚ Auth ยท Users ยท Admin ยท Applications ยท Deployments ยท Clusters โ”‚ โ”‚ Build ยท Billing ยท Lifecycle ยท Snapshots ยท Tickets ยท Access ยท โ”‚ โ”‚ Notifications ยท Kubernetes/Helm/Registry โ”‚ โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ–ผ โ–ผ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚Postgresโ”‚ โ”‚ Redis โ”‚ โ”‚ Registry โ”‚ โ”‚ Kubernetes โ”‚ โ”‚ 16 โ”‚ โ”‚(cache/ โ”‚ โ”‚ (:2) โ”‚ โ”‚ Cluster(s) โ”‚ โ”‚ โ”‚ โ”‚ Bull) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ Build Jobs โ”‚ โ”‚ โ”‚ โ”‚ (Kaniko) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ Helm releases โ”‚ โ”‚ (user apps) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐Ÿงฉ Module Overview | Module | Purpose | |--------|---------| | **Auth** | Mobile-number + OTP (SMS) and password login; JWT access/refresh; Passport strategies; role guards | | **Users** | User CRUD, profile, phone verification | | **Admin** | Super-admin user-detail dashboard and operations | | **Applications** | App CRUD, code upload (โ†’ disk), git config, runtime/version metadata | | **Application-migrations** | Import / migrate existing applications (Bull queue) | | **Build** | `build.service` โ€” runtime detection + per-runtime Dockerfile generation, Kaniko image builds inside K8s | | **Deployments** | Deploy orchestration (build โ†’ Helm), history, stop/restart | | **Kubernetes** | K8s API wrapper, Helm CLI wrapper, registry service | | **Clusters** | Multi-cluster management, kubeconfig storage, default cluster | | **Billing** | Wallet (deposit/deduct), transaction ledger, invoices, pricing catalog, coupons/discounts | | **Lifecycle** | Interval scanner: auto-suspend expired apps, auto-delete after grace period | | **Snapshots** | Application snapshot/backup & restore | | **Tickets** | Support ticket system (technical/sales departments) | | **Access** | Time-limited external access to app services via temporary NodePort grants (Bull queue) | | **Notifications** | User-facing notifications | | **Common / Config** | Shared enums, guards, decorators; env & TypeORM config | --- ## ๐Ÿ”ง Tech Stack ### Frontend: Next.js 16 (App Router) + Tailwind CSS v4 | Reason | Detail | |--------|--------| | **SSR & SEO** | Server-side rendering for fast initial loads and a public landing/blog | | **App Router** | React Server Components, layouts, locale routing under `app/[lang]/` | | **Bilingual** | `fa-IR` (default) + `en-US`; `middleware.ts` also splits landing vs authenticated panel | | **React Query** | Server state, caching, polling for live build/deploy status | | **Zustand** | Lightweight client auth store | | **TypeScript** | End-to-end type safety | ### Backend: NestJS 11 (Node.js 20) | Reason | Detail | |--------|--------| | **Modular** | Each domain is a self-contained module | | **@kubernetes/client-node** | Direct K8s API interaction (Jobs, Deployments, logs, scale) | | **Helm CLI** | Shell-out to helm for chart-based app deployments | | **Bull (Redis)** | Async queues for service-access grants and application migrations | | **TypeORM** | PostgreSQL ORM. `synchronize` is **development-only**; production schema changes ship as idempotent SQL migrations / `ALTER ... IF NOT EXISTS` | ### Build System: Kaniko (in-cluster) | Reason | Detail | |--------|--------| | **No Docker daemon** | Builds run as unprivileged K8s Jobs in `cloudhost-builds` | | **Runtime detection** | `detectRuntime()` infers Node.js / Laravel / WordPress from source files; the app may also pin a runtime explicitly | | **Per-runtime Dockerfiles** | `generateDockerfile()` emits a tailored Dockerfile for Node.js, Laravel, WordPress, Go, PHP, Python, Django, or .NET | | **WordPress** | Templated Dockerfile + custom entrypoint that merges `wp-content` | | **Source ingestion** | Uploaded archives saved to disk and streamed into a per-build PVC (helper pod + `kubectl cp`); git repos cloned in-pod | | **Registry push** | Native push to the in-cluster (insecure) registry | ### Deployment: Helm v3 Charts | Reason | Detail | |--------|--------| | **Templated manifests** | One `cloudhost-app` chart handles all runtimes + attached services | | **Rollback** | Built-in revision history | | **Persistence** | DB/app PVCs and secrets use keep policies so they survive helm uninstall | | **Ingress** | Traefik by default (k3s); `INGRESS_CLASS=nginx` for ingress-nginx | --- ## ๐Ÿ”„ Build & Deploy Flow ``` User triggers deploy (panel) โ”‚ โ–ผ Backend runs the build-and-deploy pipeline, creating a Kubernetes Job in `cloudhost-builds`: โ”Œโ”€ init: prepare source (uploaded zip โ†’ disk โ†’ helper pod + `kubectl cp` โ†’ build PVC) โ”€โ” โ”‚ โ€ฆorโ€ฆ โ”‚ โ†’ /workspace/source โ””โ”€ init: git-clone (clone repo; token injected into the URL for private repos) โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ The platform detects the runtime and generates a Dockerfile for it (Node.js / Laravel / WordPress / Go / PHP / Python / Django / .NET) โ”‚ โ–ผ container: kaniko โ†’ build image (cache per user) โ†’ push to in-cluster registry โ”‚ โ–ผ HelmService install/upgrade `cloudhost-app` โ”‚ โ–ผ Helm creates: Namespace, Deployment, Service, Ingress (+TLS), per-app DB/Redis/RabbitMQ, PVCs, Secrets, registry pull secret, log shipper โ”‚ โ–ผ App live at https://. ``` Notes: - The build runs **inline** within the deploy request (it is not queued); build progress/logs are tracked in memory and polled by the frontend. This assumes a single active backend replica for an in-flight build. - Bull/Redis queues are used by other subsystems (service-access grants, application migrations), not by the image build. --- ## ๐Ÿ” Security Architecture - Mobile-OTP + password authentication; JWT access + refresh - **Live** role/active-status enforcement โ€” `JwtStrategy` reads the user from the DB each request - Role-Based Access Control (`user` / `admin` / `technical` / `sales`) - K8s namespace isolation per user; scoped ServiceAccounts - Resource quotas & limit ranges; expandable per-app storage - Secrets stored as K8s Secrets (env vars, DB creds) - Input validation (class-validator), Helmet headers, Bcrypt password hashing --- ## ๐Ÿ’ฐ Billing & Lifecycle Flow ``` ACTIVE โ”€โ”€(expires)โ”€โ”€โ–บ SUSPENDED โ”€โ”€(grace)โ”€โ”€โ–บ PENDING_DELETION โ”€โ”€โ–บ DELETED โ–ฒ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€ payment โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€ payment (within grace) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ DOCKED โ”€โ”€ user removed the service; data retained until the plan expires ``` - **Billing cycles**: HOURLY | MONTHLY | YEARLY - **Wallet**: deposits, deductions, refunds, gateway payments; invoices with coupons/discounts - **Grace periods**: admin-configurable via the PlatformSettings entity (per cycle) - **Lifecycle scanner**: runs on an interval (default 60s); suspends expired apps (scale to 0, data retained) and deletes them after the grace period > โš ๏ธ The lifecycle scanner and other interval jobs assume a **single backend replica** โ€” > guard them (e.g. a Redis lock) before scaling the control plane horizontally. --- ## ๐Ÿ“ฆ Helm Charts ### cloudhost-platform โ€” control plane Deploys the API, UI, PostgreSQL, and Redis into a namespace (default `cloudhost`). | Template | Purpose | |----------|---------| | `backend-deployment.yaml` / `backend-service.yaml` / `backend-pvc.yaml` | NestJS API + uploads PVC | | `frontend-deployment.yaml` / `frontend-service.yaml` | Next.js UI | | `postgres-*.yaml` / `redis-*.yaml` | Control-plane database & queue | | `ingress.yaml` | Frontend / API / panel host rules (+ TLS) | | `secret.yaml` | JWT, DB, registry, SMS and other platform secrets | | `migrations-configmap.yaml` / `migrations-job.yaml` | Optional SQL migration Job (`migrations.enabled`) | | `namespace.yaml` / `_helpers.tpl` / `NOTES.txt` | Namespace + chart helpers | Key values: `ingress.enabled`, `ingress.tls.*`, `ingress.frontend.host` / `ingress.api.host`, `postgres.password`, `secrets.jwtSecret`, `migrations.enabled`. ### cloudhost-app โ€” a single user application | Template | Purpose | |----------|---------| | `deployment.yaml` | App pod (imagePullSecret, probes, WordPress volumes, env) | | `service.yaml` / `ingress.yaml` | ClusterIP + ingress with TLS | | `secret.yaml` | User env vars as a K8s Secret | | `db-deployment.yaml` / `db-service.yaml` / `db-pvc.yaml` / `db-secret.yaml` | Optional managed PostgreSQL/MySQL/MariaDB/MongoDB | | `redis-deployment.yaml` / `rabbitmq-deployment.yaml` | Optional attached services | | `app-storage-pvc.yaml` | App persistent storage | | `storageclass.yaml` | Expandable StorageClass (created on demand) | | `registry-pull-secret.yaml` | imagePullSecret for the in-cluster registry | | `fluent-bit-configmap.yaml` / `log-shipper-configmap.yaml` / `_log-shipper.tpl` / `elasticsearch-credentials-secret.yaml` | Per-app log shipping to Elasticsearch | ### cloudhost-logging โ€” observability Elasticsearch / Kibana / Fluent-bit stack for centralized build and runtime logs (also see `backend/k8s/logging/`). --- ## ๐Ÿ“ Project Structure ``` cloud-host/ โ”œโ”€โ”€ ARCHITECTURE.md README.md RUNBOOK.fa.md CHANGELOG.md CONTRIBUTING.md โ”œโ”€โ”€ UPGRADE.md UPGRADE.en.md docker-compose.yml โ”œโ”€โ”€ backend/ # NestJS 11 API โ”‚ โ”œโ”€โ”€ Dockerfile โ”‚ โ”œโ”€โ”€ helm/{cloudhost-platform, cloudhost-app, cloudhost-logging}/ โ”‚ โ”œโ”€โ”€ k8s/{logging, mail}/ # standalone manifests โ”‚ โ”œโ”€โ”€ migrations/ # SQL migrations (one-off Jobs in prod) โ”‚ โ””โ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ main.ts / app.module.ts โ”‚ โ”œโ”€โ”€ auth/ users/ admin/ # OTP auth, users, super-admin dashboard โ”‚ โ”œโ”€โ”€ applications/ application-migrations/ โ”‚ โ”œโ”€โ”€ deployments/ # orchestration (build โ†’ Helm) โ”‚ โ”œโ”€โ”€ build/ # build.service: runtime detection + per-runtime Dockerfiles + Kaniko โ”‚ โ”œโ”€โ”€ kubernetes/ # K8s client, Helm, registry โ”‚ โ”œโ”€โ”€ clusters/ # multi-cluster management โ”‚ โ”œโ”€โ”€ billing/ lifecycle/ snapshots/ tickets/ access/ notifications/ โ”‚ โ”œโ”€โ”€ common/ # enums, guards, decorators โ”‚ โ””โ”€โ”€ config/ # env + TypeORM config โ””โ”€โ”€ frontend/ # Next.js 16 (App Router, fa-IR / en-US) โ”œโ”€โ”€ Dockerfile # ARG NEXT_PUBLIC_API_URL โ””โ”€โ”€ src/ โ”œโ”€โ”€ middleware.ts # locale routing + landing/panel split โ”œโ”€โ”€ app/[lang]/{page, login, register, blog, dashboard/*} โ”œโ”€โ”€ components/ hooks/ lib/ types/ โ””โ”€โ”€ i18n/ # dictionaries, provider, switcher ``` --- ## ๐Ÿ”ฎ Future Considerations 1. Per-app horizontal autoscaling (HPA) based on CPU/memory 2. WebSocket/SSE for real-time build log streaming (currently polled) 3. A Redis-backed build queue (so builds survive a replica restart and the control plane can scale out) 4. In-cluster image vulnerability scanning (report-only) 5. GitOps integration (e.g. ArgoCD) and git-push-to-deploy 6. Automated control-plane database backups (scheduled `pg_dump` + retention) 7. App marketplace with pre-built templates