From 5f77c071836fb1706a45817727311917d077b45d Mon Sep 17 00:00:00 2001 From: keyhan Date: Wed, 22 Apr 2026 16:45:30 +0330 Subject: [PATCH] docs: rewrite ARCHITECTURE.md, README.md; add CHANGELOG and CONTRIBUTING - ARCHITECTURE.md: all modules, Helm charts, billing/lifecycle flow, WordPress - README.md: updated features, API endpoints, configuration, project structure - CHANGELOG.md: full changelog for all unreleased changes - CONTRIBUTING.md: commit conventions, documentation requirements, PR checklist --- ARCHITECTURE.md | 301 +++++++++++++++++++++++++----------------------- CHANGELOG.md | 92 +++++++++++++++ CONTRIBUTING.md | 145 +++++++++++++++++++++++ README.md | 284 +++++++++++++++++++++++---------------------- 4 files changed, 538 insertions(+), 284 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index d4e5a43..2f86985 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,7 +2,7 @@ ## Overview -CloudHost is a self-service PaaS platform that enables users to deploy Node.js and Laravel applications onto Kubernetes clusters managed by a super admin. +CloudHost is a self-service PaaS platform that enables users to deploy **Node.js**, **Laravel**, and **WordPress** applications onto Kubernetes clusters managed by a super admin. It includes a full billing/wallet system, automated lifecycle management, and Helm-based deployments. --- @@ -16,7 +16,7 @@ CloudHost is a self-service PaaS platform that enables users to deploy Node.js a │ HTTPS ▼ ┌─────────────────────────────────────────────────────────────────┐ -│ FRONTEND (Next.js) │ +│ FRONTEND (Next.js 14) │ │ ┌──────────┐ ┌───────────────┐ ┌──────────┐ ┌───────────┐ │ │ │ Auth UI │ │ Deploy Wizard │ │ Dashboard│ │Admin Panel│ │ │ └──────────┘ └───────────────┘ └──────────┘ └───────────┘ │ @@ -24,205 +24,224 @@ CloudHost is a self-service PaaS platform that enables users to deploy Node.js a │ REST API (JSON) ▼ ┌─────────────────────────────────────────────────────────────────┐ -│ BACKEND (NestJS) │ +│ BACKEND (NestJS 10) │ │ │ │ ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ │ │ │Auth │ │Applications │ │Deployments │ │Clusters │ │ │ │Module │ │Module │ │Module │ │Module │ │ │ └──────────┘ └──────────────┘ └────────────┘ └──────────┘ │ │ │ +│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ │ +│ │Billing │ │Lifecycle │ │Snapshots │ │Tickets │ │ +│ │Module │ │Module │ │Module │ │Module │ │ +│ └──────────┘ └──────────────┘ └────────────┘ └──────────┘ │ +│ │ │ ┌──────────────────┐ ┌──────────────┐ ┌──────────────────┐ │ -│ │ Kubernetes │ │ Build │ │ Logs & │ │ -│ │ Service │ │ Service │ │ Metrics Service │ │ -│ └────────┬─────────┘ └──────┬───────┘ └──────────────────┘ │ -│ │ │ │ -└───────────┼───────────────────┼──────────────────────────────────┘ - │ │ - ┌───────▼────────┐ ┌──────▼────────┐ - │ Kubernetes │ │ Container │ - │ Cluster(s) │ │ Registry │ - │ │ │ (Harbor/ECR) │ - │ ┌───────────┐ │ └───────────────┘ - │ │Namespace A│ │ - │ │ ┌─Pod────┐│ │ - │ │ │App ││ │ ┌────────────────┐ - │ │ └────────┘│ │ │ PostgreSQL │ - │ │ ┌─Pod────┐│ │ │ (Metadata DB) │ - │ │ │DB ││ │ └────────────────┘ - │ │ └────────┘│ │ - │ └───────────┘ │ - │ ┌───────────┐ │ - │ │Namespace B│ │ - │ │ ... │ │ - │ └───────────┘ │ - └───────────────┘ - +│ │ Kubernetes │ │ Helm │ │ Build │ │ +│ │ Service │ │ Service │ │ Service │ │ +│ └────────┬─────────┘ └──────┬───────┘ └──────┬───────────┘ │ +└───────────┼───────────────────┼──────────────────┼───────────────┘ + │ │ │ + ┌───────▼────────┐ ┌──────▼────────┐ ┌──────▼────────┐ + │ Kubernetes │ │ Helm CLI │ │ Kaniko │ + │ Cluster(s) │ │ (v3) │ │ (in-cluster) │ + └───────────────┘ └───────────────┘ └───────────────┘ ``` --- -## 🔧 Tech Stack Justification +## 🧩 Module Overview -### Frontend: **Next.js 14 (App Router) + Tailwind CSS** +| Module | Purpose | +|--------|---------| +| **Auth** | JWT access/refresh tokens, Passport strategies, role guards | +| **Users** | User CRUD, admin activate/deactivate, profile management | +| **Applications** | App CRUD, code upload (zip), metadata, runtime detection | +| **Build** | Kaniko-based image builds via BullMQ queue; auto-detects Node.js/Laravel/WordPress | +| **Kubernetes** | K8s API interactions — namespace, scale, delete, pod logs, build pods | +| **Helm** | Helm CLI wrapper — install/upgrade, rollback, uninstall, history | +| **Deployments** | Deployment lifecycle orchestration, history, stop/restart | +| **Clusters** | Multi-cluster management, kubeconfig storage, default cluster selection | +| **Billing** | Wallet system (deposit/deduct), transaction ledger, plan cost calculation | +| **Lifecycle** | Cron-based scanner: auto-suspend expired apps, auto-delete after grace period | +| **Snapshots** | Application snapshot/backup management | +| **Tickets** | Support ticket system for users | + +--- + +## 🔧 Tech Stack + +### Frontend: Next.js 14 (App Router) + Tailwind CSS | Reason | Detail | |--------|--------| | **SSR & SEO** | Server-side rendering for fast initial loads | -| **App Router** | Modern React Server Components, layouts, loading states | +| **App Router** | React Server Components, layouts, loading states | | **Tailwind CSS** | Rapid UI development, consistent design system | | **TypeScript** | End-to-end type safety with shared types | -| **React Query** | Efficient server state management, caching, polling for live status | +| **React Query** | Server state management, caching, polling for live status | +| **Zustand** | Lightweight client state management (auth store) | -### Backend: **NestJS (Node.js)** +### Backend: NestJS 10 (Node.js) | Reason | Detail | |--------|--------| -| **Modular architecture** | Each domain (auth, apps, deployments, clusters) is a self-contained module | +| **Modular architecture** | Each domain is a self-contained module | | **TypeScript native** | Full type safety, shared interfaces with frontend | -| **Decorator-based** | Clean controller/service pattern, guards, interceptors | -| **@kubernetes/client-node** | Official K8s client for Node.js — direct API interaction | -| **Bull/BullMQ** | Redis-backed job queues for async build & deploy pipelines | -| **TypeORM** | Mature PostgreSQL ORM with migration support | +| **@kubernetes/client-node** | Official K8s client for direct API interaction | +| **Helm CLI** | Shell-out to helm for chart-based deployments | +| **Bull/BullMQ** | Redis-backed job queues for async build pipelines | +| **TypeORM** | PostgreSQL ORM with entity-based schema | -### Database: **PostgreSQL** +### Build System: Kaniko (in-cluster) | Reason | Detail | |--------|--------| -| **ACID compliance** | Critical for deployment state tracking | -| **JSON columns** | Store flexible config/metadata without schema changes | -| **Mature ecosystem** | Battle-tested, excellent TypeORM support | -| **Scalability** | Read replicas, partitioning for growth | +| **No Docker daemon** | Builds inside K8s pods — no Docker-in-Docker | +| **Runtime detection** | Auto-detects Node.js, Laravel, WordPress from source files | +| **WordPress support** | Custom entrypoint script for wp-content merging | +| **Registry push** | Native push to insecure or authenticated registries | -### Build System: **Kaniko (in-cluster)** +### Deployment: Helm v3 Charts | Reason | Detail | |--------|--------| -| **No Docker daemon** | Builds images inside K8s pods — no Docker-in-Docker security issues | -| **Registry push** | Native push to any OCI-compatible registry | -| **Caching** | Layer caching for faster rebuilds | - -### Container Registry: **Harbor (self-hosted) or cloud-managed (ECR/GCR/ACR)** - -| Reason | Detail | -|--------|--------| -| **Private images** | User apps must not be publicly accessible | -| **Vulnerability scanning** | Harbor provides built-in image scanning | -| **Multi-tenancy** | Project-based access control | - -### Queue System: **Redis + BullMQ** - -| Reason | Detail | -|--------|--------| -| **Async builds** | Image builds are long-running — must not block API | -| **Retries** | Failed builds auto-retry with backoff | -| **Progress tracking** | Real-time build status updates | +| **Templated manifests** | Single chart handles Node.js, Laravel, WordPress | +| **Rollback support** | Built-in revision history and rollback | +| **Resource policies** | PVCs and secrets persist across helm uninstall | +| **Registry pull secrets** | Auto-created per namespace for insecure registries | --- ## 🔐 Security Architecture -``` -┌─────────────────────────────────────────┐ -│ Security Layers │ -├─────────────────────────────────────────┤ -│ │ -│ 1. JWT Authentication (access/refresh) │ -│ 2. Role-Based Access (User / Admin) │ -│ 3. K8s Namespace Isolation per user │ -│ 4. K8s RBAC — scoped ServiceAccounts │ -│ 5. Network Policies between namespaces │ -│ 6. Resource Quotas & Limit Ranges │ -│ 7. Secrets encryption (K8s Secrets) │ -│ 8. Input validation on all user inputs │ -│ 9. Rate limiting on API endpoints │ -│ │ -└─────────────────────────────────────────┘ -``` +- JWT Authentication (access + refresh tokens) +- Role-Based Access Control (User / Admin) +- K8s Namespace Isolation per user +- K8s RBAC — scoped ServiceAccounts +- Network Policies between namespaces +- Resource Quotas & Limit Ranges +- Secrets encryption (K8s Secrets) +- Input validation (class-validator on all DTOs) +- Helmet HTTP security headers +- Bcrypt password hashing (12 rounds) --- ## 🔄 Deployment Flow ``` -User uploads code ──► API receives ──► Store metadata in PostgreSQL - │ - ▼ - Queue build job (BullMQ) - │ - ▼ - Kaniko Pod builds image - │ - ▼ - Push to Container Registry - │ - ▼ - Generate K8s manifests from templates - │ - ▼ - Apply to target cluster via K8s API - │ - ▼ - Create: Namespace, Deployment, Service, - Ingress, PVC, DB, Secrets - │ - ▼ - Update deployment status in DB - │ - ▼ - User sees live status in dashboard +User uploads code (zip) + │ + ▼ +API stores file + metadata in PostgreSQL + │ + ▼ +BullMQ build job queued + │ + ▼ +detectRuntime() → nodejs | laravel | wordpress + │ + ▼ +Generate Dockerfile per runtime + │ + ▼ +Kaniko Pod builds image → pushes to registry + │ + ▼ +HelmService.installOrUpgrade() with cloudhost-app chart + │ + ▼ +Helm creates: Namespace, Deployment, Service, Ingress, + DB, PVC, Secrets, Registry Pull Secret, TLS cert + │ + ▼ +App live at https://.apps.cloudhost.ir ``` --- +## 💰 Billing & Lifecycle Flow + +``` +ACTIVE ──(expires)──► SUSPENDED ──(grace)──► PENDING_DELETION ──► DELETED + ▲ │ │ + └────── payment ────────┘ │ + └────── payment (within grace) ──────────────────┘ +``` + +- **Billing Cycles**: HOURLY | MONTHLY | YEARLY +- **Hourly plans**: auto-renew from wallet each hour +- **Grace periods**: admin-configurable via PlatformSettings table +- **Lifecycle Scanner**: runs every 60s (configurable) + +--- + +## 🚀 Helm Chart: cloudhost-app + +Single chart at `backend/helm/cloudhost-app/` handles all runtimes: + +| Template | Purpose | +|----------|---------| +| `deployment.yaml` | App pod with imagePullSecrets, probes, WordPress volumes | +| `service.yaml` | ClusterIP (port 80 → app port) | +| `ingress.yaml` | Nginx ingress with cert-manager TLS | +| `secret.yaml` | User env vars as K8s Secret | +| `db-deployment.yaml` | PostgreSQL or MySQL with health probes | +| `db-service.yaml` | Database ClusterIP service | +| `db-pvc.yaml` | Database storage (resource-policy: keep) | +| `db-secret.yaml` | Database credentials (resource-policy: keep) | +| `wp-pvc.yaml` | WordPress wp-content PVC (resource-policy: keep) | +| `registry-pull-secret.yaml` | imagePullSecret for insecure registry | + +--- + ## 📁 Project Structure ``` host/ ├── ARCHITECTURE.md ├── README.md +├── CHANGELOG.md +├── CONTRIBUTING.md ├── docker-compose.yml -├── backend/ # NestJS API -│ ├── src/ -│ │ ├── main.ts -│ │ ├── app.module.ts -│ │ ├── common/ # Shared utilities, guards, decorators -│ │ ├── config/ # Environment configuration -│ │ ├── auth/ # JWT auth, strategies, guards -│ │ ├── users/ # User management -│ │ ├── applications/ # App CRUD, code upload -│ │ ├── deployments/ # Deployment lifecycle -│ │ ├── clusters/ # K8s cluster management (admin) -│ │ ├── kubernetes/ # K8s client, manifest generation -│ │ ├── build/ # Image build pipeline -│ │ └── database/ # TypeORM entities, migrations -│ ├── templates/ # K8s YAML templates (Handlebars) +├── backend/ │ ├── Dockerfile │ ├── package.json -│ └── tsconfig.json -├── frontend/ # Next.js App +│ ├── helm/cloudhost-app/ # Helm chart for user apps │ ├── src/ -│ │ ├── app/ # App Router pages -│ │ ├── components/ # Reusable UI components -│ │ ├── lib/ # API client, utilities -│ │ ├── hooks/ # Custom React hooks -│ │ └── types/ # TypeScript interfaces +│ │ ├── main.ts / app.module.ts +│ │ ├── auth/ # JWT + Passport +│ │ ├── users/ # User management +│ │ ├── applications/ # App CRUD + upload +│ │ ├── deployments/ # Deploy orchestration +│ │ ├── clusters/ # Multi-cluster (admin) +│ │ ├── kubernetes/ # K8s client + Helm service +│ │ ├── build/ # Kaniko builds (BullMQ) +│ │ ├── billing/ # Wallet + transactions +│ │ ├── lifecycle/ # Auto-suspend/delete +│ │ ├── snapshots/ # App snapshots +│ │ └── tickets/ # Support tickets +│ └── templates/ # Legacy Handlebars (deprecated) +├── frontend/ │ ├── Dockerfile │ ├── package.json -│ └── tailwind.config.ts -└── k8s/ # Platform's own K8s deployment - ├── base/ - └── overlays/ +│ └── src/ +│ ├── app/dashboard/ # Apps, deploy, admin pages +│ ├── components/ +│ ├── lib/ # API client, auth store +│ └── types/ # Shared TS interfaces +└── uploads/ # User-uploaded code archives ``` --- -## 🚀 Future Scaling Considerations +## 🔮 Future Considerations -1. **Multi-cluster support** — Deploy to different clusters/regions -2. **Custom domains** — Let users bring their own domains with auto TLS -3. **Horizontal Pod Autoscaler** — Auto-scale based on metrics -4. **WebSocket/SSE** — Real-time build logs streaming -5. **Plugin system** — Support Python, Go, Rust runtimes -6. **Marketplace** — Pre-built app templates (WordPress, etc.) -7. **Billing integration** — Usage-based billing per resource consumption -8. **GitOps** — ArgoCD integration for declarative deployments +1. Custom domains with auto TLS via cert-manager +2. Horizontal Pod Autoscaler based on CPU/memory +3. WebSocket/SSE for real-time build log streaming +4. GitOps integration (ArgoCD) +5. Additional runtimes (Python, Go, Rust) +6. App marketplace with pre-built templates +7. Per-app resource consumption dashboards diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..254f1b3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,92 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +#### Helm Chart (`backend/helm/cloudhost-app/`) +- **New Helm chart** replacing legacy Handlebars templates for all deployments +- `deployment.yaml` — app deployment with `imagePullSecrets`, `imagePullPolicy: Always`, health probes +- `service.yaml` — ClusterIP service (port 80 → app port) +- `ingress.yaml` — Nginx ingress with cert-manager TLS +- `secret.yaml` — user env vars as K8s Secret +- `db-deployment.yaml` — PostgreSQL or MySQL with readiness/liveness probes +- `db-service.yaml` — database ClusterIP service +- `db-pvc.yaml` — database storage with `helm.sh/resource-policy: keep` +- `db-secret.yaml` — database credentials with `helm.sh/resource-policy: keep` +- `wp-pvc.yaml` — WordPress wp-content PVC with keep policy +- `registry-pull-secret.yaml` — imagePullSecret for insecure registries +- `_helpers.tpl` — shared template helpers (name, namespace, labels, DB image, DB port) +- `values.yaml` — comprehensive defaults for all runtimes +- `Chart.yaml` — chart metadata (v0.1.0) + +#### Helm Service (`backend/src/kubernetes/helm.service.ts`) +- **New HelmService** wrapping Helm CLI for install/upgrade, rollback, uninstall, history, status +- Temp file management for kubeconfig and values (mode 0o600, auto-cleanup) +- Full error handling with structured logging + +#### Lifecycle Module (`backend/src/lifecycle/`) +- **New AppLifecycleService** — cron-based scanner (configurable interval, default 60s) +- State machine: `ACTIVE → SUSPENDED → PENDING_DELETION → DELETED` +- Auto-suspend expired apps (scale to 0 replicas) +- Auto-renew hourly plans from wallet balance +- Admin-configurable grace periods via `PlatformSettings` table +- `activateApp()` and `renewApp()` for payment reactivation +- **New LifecycleController** — `GET/PATCH /lifecycle/settings` (admin only) +- **New LifecycleModule** — wires service, controller, entities + +#### Billing Enhancements (`backend/src/billing/`) +- **PlatformSetting entity** — key-value settings table for admin runtime config +- `calculateCostForApp()` method in BillingService +- `deductWallet()` method for programmatic wallet deductions +- Billing controller integrates lifecycle activation on payment + +#### Application Entity Enhancements +- New fields: `planId`, `billingCycle`, `lifecycleStatus`, `planExpiresAt`, `suspendedAt`, `scheduledDeletionAt` +- `AppLifecycleStatus` enum: `active`, `suspended`, `pending_deletion`, `deleted` +- `BillingCycle` enum: `hourly`, `monthly`, `yearly` + +#### Frontend +- Wallet balance display in dashboard header (all pages) +- Lifecycle status column in user apps list (color-coded badges) +- Plan expiry countdown in apps list +- Admin apps page: suspended/pending-deletion summary cards +- Admin billing page: lifecycle settings management section +- Updated TypeScript types for lifecycle and billing fields + +#### Tests +- `build.service.spec.ts` — WordPress Dockerfile generation, PVC race condition, entrypoint script +- `helm.service.spec.ts` — HelmService chart path, temp files, history parsing +- `kubernetes.service.spec.ts` — `buildHelmValues()` logic, password generation +- `clusters.service.spec.ts` — getDefault logic, delete/reassign logic + +### Changed + +#### Build Service (`backend/src/build/build.service.ts`) +- **Runtime detection** — `detectRuntime()` now reads parent directory (not zip file itself) +- **WordPress support** — full Dockerfile generation with custom entrypoint for wp-content merging +- **Laravel fix** — generates `nginx.conf` and `supervisord.conf` inline (no longer requires user-provided files) +- **Laravel fix** — `composer.lock` made optional (`composer.lock*`) +- ConfigMap cleanup moved to `finally` block + +#### Kubernetes Service (`backend/src/kubernetes/kubernetes.service.ts`) +- `buildHelmValues()` now includes `registry.url` for pull secret generation +- `deleteApplication()` rewritten — runs `helm uninstall` then explicitly deletes kept resources (PVCs, secrets, TLS certs) +- Added `scaleDeployment()` method for lifecycle suspend/resume + +#### Applications Controller +- Delete endpoint no longer requires `app.clusterId && app.latestImageTag` — always attempts K8s cleanup + +#### Configuration +- Added `lifecycle` config section with `scanIntervalMs` and per-cycle `deleteAfterMs` defaults + +### Documentation +- **ARCHITECTURE.md** — complete rewrite: added WordPress, Helm charts, billing/lifecycle, all modules +- **README.md** — complete rewrite: added WordPress, billing, lifecycle, snapshots, tickets, new API endpoints +- **CHANGELOG.md** — created (this file) +- **CONTRIBUTING.md** — created with commit conventions, documentation requirements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..87746bf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,145 @@ +# Contributing to CloudHost + +## Commit Conventions + +This project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). + +### Format + +``` +(): + +[optional body] + +[optional footer(s)] +``` + +### Types + +| Type | When to use | +|------|-------------| +| `feat` | New feature or capability | +| `fix` | Bug fix | +| `refactor` | Code change that neither fixes a bug nor adds a feature | +| `docs` | Documentation only changes | +| `test` | Adding or updating tests | +| `chore` | Build process, CI, dependency updates | +| `perf` | Performance improvement | +| `style` | Code style (formatting, semicolons, etc.) | + +### Scopes + +| Scope | Area | +|-------|------| +| `build` | Build service, Kaniko, Dockerfile generation | +| `helm` | Helm chart templates and values | +| `k8s` | Kubernetes service, cluster management | +| `billing` | Wallet, transactions, plans | +| `lifecycle` | Auto-suspend/delete scanner | +| `auth` | Authentication, JWT, guards | +| `apps` | Applications module | +| `deploy` | Deployments module | +| `frontend` | Next.js frontend | +| `docs` | Documentation files | +| `deps` | Dependency changes | + +### Examples + +``` +feat(helm): add WordPress wp-content PVC template +fix(build): detect runtime from parent dir not zip file +feat(lifecycle): add cron-based app suspension scanner +docs: update ARCHITECTURE.md with billing flow +test(k8s): add buildHelmValues unit tests +refactor(billing): extract calculateCostForApp method +``` + +--- + +## Documentation Requirements + +### When to Update Docs + +Every change **must** include documentation updates where applicable: + +1. **New module/service** → Update `ARCHITECTURE.md` module table + project structure +2. **New API endpoint** → Update `README.md` API endpoints section +3. **New env variable** → Update `README.md` configuration table + `configuration.ts` +4. **New Helm template** → Update `ARCHITECTURE.md` Helm chart table +5. **Breaking change** → Add `BREAKING CHANGE:` footer in commit + update CHANGELOG + +### CHANGELOG + +Update `CHANGELOG.md` under `[Unreleased]` for every PR: + +- **Added** — new features +- **Changed** — changes to existing functionality +- **Deprecated** — soon-to-be removed features +- **Removed** — removed features +- **Fixed** — bug fixes +- **Security** — vulnerability fixes + +--- + +## Development Workflow + +### Branch Strategy + +``` +main ← production-ready + └── feat/* ← feature branches + └── fix/* ← bug fix branches + └── refactor/* ← refactoring branches +``` + +### PR Checklist + +Before submitting a PR: + +- [ ] Code compiles: `cd backend && npx tsc --noEmit` +- [ ] Frontend compiles: `cd frontend && npx tsc --noEmit` +- [ ] Helm chart lints: `helm lint backend/helm/cloudhost-app` +- [ ] Tests pass: `cd backend && npm test` +- [ ] CHANGELOG.md updated +- [ ] Documentation updated (if applicable) +- [ ] No `console.log` left in production code (use `Logger` service) + +### Code Style + +- **TypeScript strict mode** — no `any` unless explicitly justified +- **NestJS patterns** — use decorators, dependency injection, modules +- **Logging** — use NestJS `Logger` service, not `console.log` +- **Error handling** — use NestJS exceptions (`NotFoundException`, `BadRequestException`, etc.) +- **Naming** — `camelCase` for variables/methods, `PascalCase` for classes/types, `kebab-case` for files + +--- + +## Testing + +### Unit Tests + +```bash +cd backend && npm test +``` + +Tests are co-located with source files (`*.spec.ts`): + +| Test file | Coverage | +|-----------|----------| +| `build.service.spec.ts` | WordPress Dockerfile, runtime detection, PVC cleanup | +| `helm.service.spec.ts` | Chart path resolution, temp file management | +| `kubernetes.service.spec.ts` | Helm values building, password generation | +| `clusters.service.spec.ts` | Default cluster selection, delete/reassign | + +### Validation + +```bash +# Backend TypeScript +cd backend && npx tsc --noEmit + +# Frontend TypeScript +cd frontend && npx tsc --noEmit + +# Helm chart +helm lint backend/helm/cloudhost-app +``` diff --git a/README.md b/README.md index 1ccc2da..74b6fd1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ☁️ CloudHost — Self-Service PaaS Platform -A self-service Platform-as-a-Service (PaaS) that lets developers deploy **Node.js** and **Laravel** applications onto Kubernetes with zero DevOps overhead. Super admins manage clusters, quotas, and users; developers simply push code and deploy. +A self-service Platform-as-a-Service (PaaS) that lets developers deploy **Node.js**, **Laravel**, and **WordPress** applications onto Kubernetes with zero DevOps overhead. Includes wallet-based billing, automated lifecycle management, and Helm-based deployments. --- @@ -23,27 +23,35 @@ A self-service Platform-as-a-Service (PaaS) that lets developers deploy **Node.j | Frontend | Next.js 14, Tailwind CSS, React Query, Zustand | | Backend API | NestJS 10, TypeORM, Passport JWT, Bull (Redis) | | Build Engine | Kaniko (in-cluster, daemon-less Docker builds) | -| Orchestrator | @kubernetes/client-node, Handlebars YAML templates | +| Deployment | Helm v3 charts, @kubernetes/client-node | | Database | PostgreSQL 16 | | Queue | Redis 7 + BullMQ | +> 📖 See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed system design. + --- ## Features ### For Developers -- 🚀 **One-click deploys** from a Git URL or uploaded code archive -- 🟢 **Node.js** (with `npm run build` & `npm start`) support -- 🟣 **Laravel** (PHP 8.3 + Nginx + Supervisor) support -- 🗄️ **Managed databases** — PostgreSQL or MySQL provisioned automatically -- 📊 **Live logs** & deployment history +- 🚀 **One-click deploys** from uploaded code archive (zip) +- 🟢 **Node.js** — auto-detected via `package.json` (npm build & start) +- 🟣 **Laravel** — PHP 8.x + Nginx + Supervisor (auto-detected via `artisan`) +- 🔵 **WordPress** — official image + custom entrypoint for wp-content merging +- 🗄️ **Managed databases** — PostgreSQL or MySQL provisioned via Helm +- 💰 **Wallet system** — deposit funds, pay for plans (hourly/monthly/yearly) +- 📊 **Live logs** & deployment history with rollback - 🔒 **Environment variables** managed as Kubernetes Secrets - ⚙️ **Resource controls** — CPU, memory, replica count +- 📸 **Snapshots** — backup and restore application state +- 🎫 **Support tickets** — in-app support system ### For Super Admins - 🖥️ **Multi-cluster management** — register/remove Kubernetes clusters - 👥 **User management** — activate, deactivate, change roles - 📈 **Quotas** — per-cluster limits (CPU, memory, max apps) +- 💳 **Billing oversight** — view all transactions, manage wallet deposits +- ⏱️ **Lifecycle settings** — configure grace periods per billing cycle - 🔐 **RBAC** — role-based guards on every endpoint --- @@ -53,39 +61,52 @@ A self-service Platform-as-a-Service (PaaS) that lets developers deploy **Node.j ``` host/ ├── ARCHITECTURE.md # Detailed architecture document +├── README.md # This file +├── CHANGELOG.md # Version history +├── CONTRIBUTING.md # Development workflow & conventions ├── docker-compose.yml # Local dev / production compose │ ├── backend/ # NestJS API │ ├── Dockerfile │ ├── package.json +│ ├── helm/ +│ │ └── cloudhost-app/ # Helm chart (all runtimes) +│ │ ├── Chart.yaml +│ │ ├── values.yaml +│ │ └── templates/ # K8s manifest templates │ ├── src/ -│ │ ├── main.ts -│ │ ├── app.module.ts +│ │ ├── main.ts / app.module.ts │ │ ├── auth/ # JWT auth (register, login, refresh) │ │ ├── users/ # User CRUD + admin ops -│ │ ├── applications/ # Application CRUD +│ │ ├── applications/ # Application CRUD + code upload │ │ ├── deployments/ # Deployment pipeline orchestration │ │ ├── clusters/ # Cluster management (admin) -│ │ ├── kubernetes/ # K8s client & manifest generator +│ │ ├── kubernetes/ # K8s client + Helm service │ │ ├── build/ # Kaniko build jobs (Bull queue) +│ │ ├── billing/ # Wallet, transactions, plan costs +│ │ ├── lifecycle/ # Auto-suspend/delete scanner +│ │ ├── snapshots/ # App snapshot management +│ │ ├── tickets/ # Support ticket system │ │ ├── common/ # Enums, decorators, guards │ │ └── config/ # Env configuration loader -│ └── templates/ # Handlebars K8s YAML templates +│ └── templates/ # Legacy Handlebars templates (deprecated) │ -└── frontend/ # Next.js 14 App Router - ├── Dockerfile - ├── package.json - └── src/ - ├── app/ - │ ├── login/ # Auth pages - │ ├── register/ - │ └── dashboard/ # Protected dashboard - │ ├── apps/ # App list & detail - │ ├── deploy/ # 4-step deploy wizard - │ └── admin/ # Admin: users & clusters - ├── components/ - ├── lib/ # API client, auth store - └── types/ # TypeScript interfaces +├── frontend/ # Next.js 14 App Router +│ ├── Dockerfile +│ ├── package.json +│ └── src/ +│ ├── app/ +│ │ ├── login/ & register/ +│ │ └── dashboard/ +│ │ ├── apps/ # App list + detail (lifecycle status) +│ │ ├── deploy/ # Multi-step deploy wizard +│ │ └── admin/ # Admin: users, clusters, billing, apps +│ ├── components/ +│ ├── lib/ # API client, auth store +│ ├── hooks/ +│ └── types/ # TypeScript interfaces +│ +└── uploads/ # User-uploaded code archives ``` --- @@ -98,151 +119,149 @@ host/ | --------------- | ------- | | Node.js | ≥ 20 | | Docker & Compose| ≥ 24 | -| PostgreSQL | 16 (or use Docker) | -| Redis | 7 (or use Docker) | +| PostgreSQL | 16 | +| Redis | 7 | +| Helm | ≥ 3.12 | ### 1. Clone & Install ```bash git clone host && cd host - -# Backend cd backend && npm install && cd .. - -# Frontend cd frontend && npm install && cd .. ``` ### 2. Environment Variables ```bash -# Backend cp backend/.env.example backend/.env -# Edit backend/.env with your DB, JWT, Redis, and registry settings - -# Frontend cp frontend/.env.local.example frontend/.env.local +# Edit both files with your DB, JWT, Redis, and registry settings ``` -### 3. Run with Docker Compose (recommended) +### 3. Run with Docker Compose ```bash docker compose up --build ``` -This spins up **PostgreSQL**, **Redis**, **Backend** (port 4000), and **Frontend** (port 3000). - -Open [http://localhost:3000](http://localhost:3000) in your browser. +Backend at port 4000, Frontend at port 3000. ### 4. Run Locally (development) ```bash # Terminal 1 — Backend -cd backend -npm run start:dev +cd backend && npm run start:dev # Terminal 2 — Frontend -cd frontend -npm run dev +cd frontend && npm run dev ``` --- ## API Endpoints -All endpoints are prefixed with `/api/v1`. +All endpoints prefixed with `/api/v1`. Full Swagger docs at `http://localhost:4000/docs`. ### Auth -| Method | Path | Description | -| ------ | ----------------- | ------------------- | -| POST | /auth/register | Create account | -| POST | /auth/login | Get JWT tokens | -| POST | /auth/refresh | Refresh access token| +| Method | Path | Description | +|--------|------|-------------| +| POST | /auth/register | Create account | +| POST | /auth/login | Get JWT tokens | +| POST | /auth/refresh | Refresh access token | ### Applications -| Method | Path | Description | -| ------ | ------------------ | ------------------- | -| POST | /applications | Create app | -| GET | /applications | List user's apps | -| GET | /applications/:id | Get app details | -| PATCH | /applications/:id | Update app | -| DELETE | /applications/:id | Delete app | +| Method | Path | Description | +|--------|------|-------------| +| POST | /applications | Create app | +| GET | /applications | List user's apps | +| GET | /applications/:id | App details | +| PATCH | /applications/:id | Update app | +| DELETE | /applications/:id | Delete app + K8s resources | ### Deployments -| Method | Path | Description | -| ------ | ------------------------------------ | -------------------- | -| POST | /applications/:appId/deployments | Trigger deploy | -| GET | /applications/:appId/deployments | List deployments | -| GET | /deployments/:id | Deployment detail | -| GET | /deployments/:id/logs | Get pod logs | -| POST | /deployments/:id/stop | Stop deployment | -| POST | /deployments/:id/restart | Restart deployment | +| Method | Path | Description | +|--------|------|-------------| +| POST | /applications/:appId/deployments | Trigger deploy | +| GET | /applications/:appId/deployments | List deployments | +| GET | /deployments/:id | Deployment detail | +| GET | /deployments/:id/logs | Pod logs | +| POST | /deployments/:id/stop | Stop deployment | +| POST | /deployments/:id/restart | Restart deployment | -### Users (authenticated) -| Method | Path | Description | -| ------ | ---------- | ---------------- | -| GET | /users/me | Current user | -| PATCH | /users/me | Update profile | +### Billing +| Method | Path | Description | +|--------|------|-------------| +| GET | /billing/balance | Get wallet balance | +| POST | /billing/deposit | Add funds to wallet | +| GET | /billing/transactions | Transaction history | +| POST | /billing/pay/:appId | Pay for app plan | + +### Lifecycle (Admin) +| Method | Path | Description | +|--------|------|-------------| +| GET | /lifecycle/settings | Get retention periods | +| PATCH | /lifecycle/settings | Update retention periods | + +### Snapshots +| Method | Path | Description | +|--------|------|-------------| +| POST | /snapshots | Create snapshot | +| GET | /snapshots | List snapshots | +| POST | /snapshots/:id/restore | Restore snapshot | + +### Tickets +| Method | Path | Description | +|--------|------|-------------| +| POST | /tickets | Create ticket | +| GET | /tickets | List tickets | +| PATCH | /tickets/:id | Update ticket | + +### Users +| Method | Path | Description | +|--------|------|-------------| +| GET | /users/me | Current user | +| PATCH | /users/me | Update profile | ### Admin — Users -| Method | Path | Description | -| ------ | ------------------------------ | ------------------ | -| GET | /users | List all users | -| PATCH | /users/:id/activate | Activate user | -| PATCH | /users/:id/deactivate | Deactivate user | -| PATCH | /users/:id/role | Change role | +| Method | Path | Description | +|--------|------|-------------| +| GET | /users | List all users | +| PATCH | /users/:id/activate | Activate user | +| PATCH | /users/:id/deactivate | Deactivate user | +| PATCH | /users/:id/role | Change role | ### Admin — Clusters -| Method | Path | Description | -| ------ | --------------- | ----------------- | -| POST | /clusters | Add cluster | -| GET | /clusters | List clusters | -| GET | /clusters/:id | Cluster details | -| PATCH | /clusters/:id | Update cluster | -| DELETE | /clusters/:id | Remove cluster | - -> 📖 Full Swagger docs available at `http://localhost:4000/docs` when the backend is running. +| Method | Path | Description | +|--------|------|-------------| +| POST | /clusters | Add cluster | +| GET | /clusters | List clusters | +| GET | /clusters/:id | Cluster details | +| PATCH | /clusters/:id | Update cluster | +| DELETE | /clusters/:id | Remove cluster | --- -## Deployment Flow +## Configuration -``` -Developer creates app → Uploads code / provides Git URL - │ - ▼ - Build Service creates Kaniko Job in K8s - │ - ▼ - Kaniko builds Docker image → Pushes to Container Registry - │ - ▼ - Kubernetes Service generates manifests from Handlebars templates: - • Namespace • Deployment • Service • Ingress - • Database (optional) • PVC • Secret - │ - ▼ - Applies manifests to target cluster via @kubernetes/client-node - │ - ▼ - App is live at https://.apps.yourdomain.com -``` - ---- - -## Kubernetes Templates - -The platform dynamically generates K8s manifests using **Handlebars** templates located in `backend/templates/`: - -| Template | Purpose | -| ----------------- | --------------------------------------------- | -| `namespace.yaml` | Per-user namespace with resource quotas | -| `deployment.yaml` | App deployment with health probes & resources | -| `service.yaml` | ClusterIP service | -| `ingress.yaml` | Ingress with TLS (cert-manager annotations) | -| `database.yaml` | PostgreSQL or MySQL StatefulSet | -| `pvc.yaml` | Persistent volume claim for databases | -| `secret.yaml` | Environment variables as K8s Secrets | +| Variable | Description | Default | +|----------|-------------|---------| +| `PORT` | Backend port | `4000` | +| `DB_HOST` | PostgreSQL host | `localhost` | +| `DB_PORT` | PostgreSQL port | `5432` | +| `DB_USERNAME` | Database user | `cloudhost` | +| `DB_PASSWORD` | Database password | — | +| `DB_NAME` | Database name | `cloudhost` | +| `JWT_SECRET` | JWT signing secret | — | +| `JWT_EXPIRES_IN` | Access token TTL | `15m` | +| `REDIS_HOST` | Redis host | `localhost` | +| `REDIS_PORT` | Redis port | `6379` | +| `REGISTRY_URL` | Container registry URL | `localhost:30500` | +| `PLATFORM_DOMAIN` | Base domain for app subdomains | `apps.cloudhost.ir` | +| `LIFECYCLE_SCAN_INTERVAL_MS` | Lifecycle scanner interval | `60000` | +| `LIFECYCLE_HOURLY_DELETE_AFTER_MS` | Hourly plan grace period | `3600000` (1h) | +| `LIFECYCLE_MONTHLY_DELETE_AFTER_MS` | Monthly plan grace period | `259200000` (3d) | +| `LIFECYCLE_YEARLY_DELETE_AFTER_MS` | Yearly plan grace period | `604800000` (7d) | --- @@ -258,27 +277,6 @@ The platform dynamically generates K8s manifests using **Handlebars** templates --- -## Configuration - -All configuration is via environment variables. See `backend/.env.example` for the full list: - -| Variable | Description | Default | -| ------------------- | -------------------------------- | ----------------- | -| `PORT` | Backend port | `4000` | -| `DB_HOST` | PostgreSQL host | `localhost` | -| `DB_PORT` | PostgreSQL port | `5432` | -| `DB_USERNAME` | Database user | `cloudhost` | -| `DB_PASSWORD` | Database password | — | -| `DB_NAME` | Database name | `cloudhost` | -| `JWT_SECRET` | JWT signing secret | — | -| `JWT_EXPIRES_IN` | Access token TTL | `15m` | -| `REDIS_HOST` | Redis host | `localhost` | -| `REDIS_PORT` | Redis port | `6379` | -| `REGISTRY_URL` | Container registry URL | — | -| `PLATFORM_DOMAIN` | Base domain for app subdomains | `apps.localhost` | - ---- - ## License MIT