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
This commit is contained in:
keyhan
2026-04-22 16:45:30 +03:30
parent e10f9c5235
commit 5f77c07183
4 changed files with 538 additions and 284 deletions
+160 -141
View File
@@ -2,7 +2,7 @@
## Overview ## 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 │ HTTPS
┌─────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND (Next.js) │ FRONTEND (Next.js 14)
│ ┌──────────┐ ┌───────────────┐ ┌──────────┐ ┌───────────┐ │ │ ┌──────────┐ ┌───────────────┐ ┌──────────┐ ┌───────────┐ │
│ │ Auth UI │ │ Deploy Wizard │ │ Dashboard│ │Admin Panel│ │ │ │ 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) │ REST API (JSON)
┌─────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────┐
│ BACKEND (NestJS) │ BACKEND (NestJS 10)
│ │ │ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ │ │ ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ │
│ │Auth │ │Applications │ │Deployments │ │Clusters │ │ │ │Auth │ │Applications │ │Deployments │ │Clusters │ │
│ │Module │ │Module │ │Module │ │Module │ │ │ │Module │ │Module │ │Module │ │Module │ │
│ └──────────┘ └──────────────┘ └────────────┘ └──────────┘ │ │ └──────────┘ └──────────────┘ └────────────┘ └──────────┘ │
│ │ │ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ │
│ │Billing │ │Lifecycle │ │Snapshots │ │Tickets │ │
│ │Module │ │Module │ │Module │ │Module │ │
│ └──────────┘ └──────────────┘ └────────────┘ └──────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ ┌──────────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Kubernetes │ │ Build │ │ Logs & │ │ │ │ Kubernetes │ │ Helm │ │ Build │ │
│ │ Service │ │ Service │ │ Metrics Service │ │ │ │ Service │ │ Service │ │ Service │ │
│ └────────┬─────────┘ └──────┬───────┘ └─────────────────┘ │ │ └────────┬─────────┘ └──────┬───────┘ └─────────────────┘ │
│ │ │ │ └───────────┼───────────────────┼──────────────────┼───────────────┘
└───────────┼───────────────────┼──────────────────────────────────┘ │ │ │
│ │ ┌───────▼────────┐ ┌──────▼────────┐ ┌──────▼────────┐
┌───────▼────────┐ ┌──────▼────────┐ │ Kubernetes │ │ Helm CLI │ │ Kaniko │
Kubernetes│ Container Cluster(s) (v3) │ │ (in-cluster)
│ Cluster(s) │ │ Registry │ └───────────────┘ └───────────────┘ └───────────────┘
│ │ │ (Harbor/ECR) │
│ ┌───────────┐ │ └───────────────┘
│ │Namespace A│ │
│ │ ┌─Pod────┐│ │
│ │ │App ││ │ ┌────────────────┐
│ │ └────────┘│ │ │ PostgreSQL │
│ │ ┌─Pod────┐│ │ │ (Metadata DB) │
│ │ │DB ││ │ └────────────────┘
│ │ └────────┘│ │
│ └───────────┘ │
│ ┌───────────┐ │
│ │Namespace B│ │
│ │ ... │ │
│ └───────────┘ │
└───────────────┘
``` ```
--- ---
## 🔧 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 | | Reason | Detail |
|--------|--------| |--------|--------|
| **SSR & SEO** | Server-side rendering for fast initial loads | | **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 | | **Tailwind CSS** | Rapid UI development, consistent design system |
| **TypeScript** | End-to-end type safety with shared types | | **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 | | 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 | | **TypeScript native** | Full type safety, shared interfaces with frontend |
| **Decorator-based** | Clean controller/service pattern, guards, interceptors | | **@kubernetes/client-node** | Official K8s client for direct API interaction |
| **@kubernetes/client-node** | Official K8s client for Node.js — direct API interaction | | **Helm CLI** | Shell-out to helm for chart-based deployments |
| **Bull/BullMQ** | Redis-backed job queues for async build & deploy pipelines | | **Bull/BullMQ** | Redis-backed job queues for async build pipelines |
| **TypeORM** | Mature PostgreSQL ORM with migration support | | **TypeORM** | PostgreSQL ORM with entity-based schema |
### Database: **PostgreSQL** ### Build System: Kaniko (in-cluster)
| Reason | Detail | | Reason | Detail |
|--------|--------| |--------|--------|
| **ACID compliance** | Critical for deployment state tracking | | **No Docker daemon** | Builds inside K8s pods — no Docker-in-Docker |
| **JSON columns** | Store flexible config/metadata without schema changes | | **Runtime detection** | Auto-detects Node.js, Laravel, WordPress from source files |
| **Mature ecosystem** | Battle-tested, excellent TypeORM support | | **WordPress support** | Custom entrypoint script for wp-content merging |
| **Scalability** | Read replicas, partitioning for growth | | **Registry push** | Native push to insecure or authenticated registries |
### Build System: **Kaniko (in-cluster)** ### Deployment: Helm v3 Charts
| Reason | Detail | | Reason | Detail |
|--------|--------| |--------|--------|
| **No Docker daemon** | Builds images inside K8s pods — no Docker-in-Docker security issues | | **Templated manifests** | Single chart handles Node.js, Laravel, WordPress |
| **Registry push** | Native push to any OCI-compatible registry | | **Rollback support** | Built-in revision history and rollback |
| **Caching** | Layer caching for faster rebuilds | | **Resource policies** | PVCs and secrets persist across helm uninstall |
| **Registry pull secrets** | Auto-created per namespace for insecure registries |
### 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 |
--- ---
## 🔐 Security Architecture ## 🔐 Security Architecture
``` - JWT Authentication (access + refresh tokens)
┌─────────────────────────────────────────┐ - Role-Based Access Control (User / Admin)
│ Security Layers │ - K8s Namespace Isolation per user
├─────────────────────────────────────────┤ - K8s RBAC — scoped ServiceAccounts
│ │ - Network Policies between namespaces
│ 1. JWT Authentication (access/refresh) │ - Resource Quotas & Limit Ranges
│ 2. Role-Based Access (User / Admin) │ - Secrets encryption (K8s Secrets)
│ 3. K8s Namespace Isolation per user │ - Input validation (class-validator on all DTOs)
│ 4. K8s RBAC — scoped ServiceAccounts │ - Helmet HTTP security headers
│ 5. Network Policies between namespaces │ - Bcrypt password hashing (12 rounds)
│ 6. Resource Quotas & Limit Ranges │
│ 7. Secrets encryption (K8s Secrets) │
│ 8. Input validation on all user inputs │
│ 9. Rate limiting on API endpoints │
│ │
└─────────────────────────────────────────┘
```
--- ---
## 🔄 Deployment Flow ## 🔄 Deployment Flow
``` ```
User uploads code ──► API receives ──► Store metadata in PostgreSQL User uploads code (zip)
Queue build job (BullMQ) API stores file + metadata in PostgreSQL
Kaniko Pod builds image BullMQ build job queued
Push to Container Registry detectRuntime() → nodejs | laravel | wordpress
Generate K8s manifests from templates Generate Dockerfile per runtime
Apply to target cluster via K8s API Kaniko Pod builds image → pushes to registry
Create: Namespace, Deployment, Service, HelmService.installOrUpgrade() with cloudhost-app chart
Ingress, PVC, DB, Secrets
Helm creates: Namespace, Deployment, Service, Ingress,
Update deployment status in DB DB, PVC, Secrets, Registry Pull Secret, TLS cert
User sees live status in dashboard App live at https://<subdomain>.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 ## 📁 Project Structure
``` ```
host/ host/
├── ARCHITECTURE.md ├── ARCHITECTURE.md
├── README.md ├── README.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── docker-compose.yml ├── docker-compose.yml
├── backend/ # NestJS API ├── backend/
│ ├── 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)
│ ├── Dockerfile │ ├── Dockerfile
│ ├── package.json │ ├── package.json
── tsconfig.json ── helm/cloudhost-app/ # Helm chart for user apps
├── frontend/ # Next.js App
│ ├── src/ │ ├── src/
│ │ ├── app/ # App Router pages │ │ ├── main.ts / app.module.ts
│ │ ├── components/ # Reusable UI components │ │ ├── auth/ # JWT + Passport
│ │ ├── lib/ # API client, utilities │ │ ├── users/ # User management
│ │ ├── hooks/ # Custom React hooks │ │ ├── applications/ # App CRUD + upload
│ │ ── types/ # TypeScript interfaces │ │ ── 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 │ ├── Dockerfile
│ ├── package.json │ ├── package.json
│ └── tailwind.config.ts │ └── src/
└── k8s/ # Platform's own K8s deployment │ ├── app/dashboard/ # Apps, deploy, admin pages
├── base/ ├── components/
── overlays/ ── 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 1. Custom domains with auto TLS via cert-manager
2. **Custom domains** — Let users bring their own domains with auto TLS 2. Horizontal Pod Autoscaler based on CPU/memory
3. **Horizontal Pod Autoscaler** — Auto-scale based on metrics 3. WebSocket/SSE for real-time build log streaming
4. **WebSocket/SSE** — Real-time build logs streaming 4. GitOps integration (ArgoCD)
5. **Plugin system** — Support Python, Go, Rust runtimes 5. Additional runtimes (Python, Go, Rust)
6. **Marketplace** — Pre-built app templates (WordPress, etc.) 6. App marketplace with pre-built templates
7. **Billing integration** — Usage-based billing per resource consumption 7. Per-app resource consumption dashboards
8. **GitOps** — ArgoCD integration for declarative deployments
+92
View File
@@ -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
+145
View File
@@ -0,0 +1,145 @@
# Contributing to CloudHost
## Commit Conventions
This project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
### Format
```
<type>(<scope>): <short description>
[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
```
+141 -143
View File
@@ -1,6 +1,6 @@
# ☁️ CloudHost — Self-Service PaaS Platform # ☁️ 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 | | Frontend | Next.js 14, Tailwind CSS, React Query, Zustand |
| Backend API | NestJS 10, TypeORM, Passport JWT, Bull (Redis) | | Backend API | NestJS 10, TypeORM, Passport JWT, Bull (Redis) |
| Build Engine | Kaniko (in-cluster, daemon-less Docker builds) | | 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 | | Database | PostgreSQL 16 |
| Queue | Redis 7 + BullMQ | | Queue | Redis 7 + BullMQ |
> 📖 See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed system design.
--- ---
## Features ## Features
### For Developers ### For Developers
- 🚀 **One-click deploys** from a Git URL or uploaded code archive - 🚀 **One-click deploys** from uploaded code archive (zip)
- 🟢 **Node.js** (with `npm run build` & `npm start`) support - 🟢 **Node.js** — auto-detected via `package.json` (npm build & start)
- 🟣 **Laravel** (PHP 8.3 + Nginx + Supervisor) support - 🟣 **Laravel** PHP 8.x + Nginx + Supervisor (auto-detected via `artisan`)
- 🗄️ **Managed databases** — PostgreSQL or MySQL provisioned automatically - 🔵 **WordPress** — official image + custom entrypoint for wp-content merging
- 📊 **Live logs** & deployment history - 🗄️ **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 - 🔒 **Environment variables** managed as Kubernetes Secrets
- ⚙️ **Resource controls** — CPU, memory, replica count - ⚙️ **Resource controls** — CPU, memory, replica count
- 📸 **Snapshots** — backup and restore application state
- 🎫 **Support tickets** — in-app support system
### For Super Admins ### For Super Admins
- 🖥️ **Multi-cluster management** — register/remove Kubernetes clusters - 🖥️ **Multi-cluster management** — register/remove Kubernetes clusters
- 👥 **User management** — activate, deactivate, change roles - 👥 **User management** — activate, deactivate, change roles
- 📈 **Quotas** — per-cluster limits (CPU, memory, max apps) - 📈 **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 - 🔐 **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/ host/
├── ARCHITECTURE.md # Detailed architecture document ├── 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 ├── docker-compose.yml # Local dev / production compose
├── backend/ # NestJS API ├── backend/ # NestJS API
│ ├── Dockerfile │ ├── Dockerfile
│ ├── package.json │ ├── package.json
│ ├── helm/
│ │ └── cloudhost-app/ # Helm chart (all runtimes)
│ │ ├── Chart.yaml
│ │ ├── values.yaml
│ │ └── templates/ # K8s manifest templates
│ ├── src/ │ ├── src/
│ │ ├── main.ts │ │ ├── main.ts / app.module.ts
│ │ ├── app.module.ts
│ │ ├── auth/ # JWT auth (register, login, refresh) │ │ ├── auth/ # JWT auth (register, login, refresh)
│ │ ├── users/ # User CRUD + admin ops │ │ ├── users/ # User CRUD + admin ops
│ │ ├── applications/ # Application CRUD │ │ ├── applications/ # Application CRUD + code upload
│ │ ├── deployments/ # Deployment pipeline orchestration │ │ ├── deployments/ # Deployment pipeline orchestration
│ │ ├── clusters/ # Cluster management (admin) │ │ ├── clusters/ # Cluster management (admin)
│ │ ├── kubernetes/ # K8s client & manifest generator │ │ ├── kubernetes/ # K8s client + Helm service
│ │ ├── build/ # Kaniko build jobs (Bull queue) │ │ ├── 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 │ │ ├── common/ # Enums, decorators, guards
│ │ └── config/ # Env configuration loader │ │ └── config/ # Env configuration loader
│ └── templates/ # Handlebars K8s YAML templates │ └── templates/ # Legacy Handlebars templates (deprecated)
── frontend/ # Next.js 14 App Router ── frontend/ # Next.js 14 App Router
├── Dockerfile ├── Dockerfile
├── package.json ├── package.json
└── src/ └── src/
├── app/ ├── app/
│ ├── login/ # Auth pages │ ├── login/ & register/
── register/ ── dashboard/
└── dashboard/ # Protected dashboard ├── apps/ # App list + detail (lifecycle status)
│ ├── apps/ # App list & detail │ ├── deploy/ # Multi-step deploy wizard
── deploy/ # 4-step deploy wizard ── admin/ # Admin: users, clusters, billing, apps
── admin/ # Admin: users & clusters ── components/
├── components/ ├── lib/ # API client, auth store
├── lib/ # API client, auth store ├── hooks/
└── types/ # TypeScript interfaces └── types/ # TypeScript interfaces
└── uploads/ # User-uploaded code archives
``` ```
--- ---
@@ -98,151 +119,149 @@ host/
| --------------- | ------- | | --------------- | ------- |
| Node.js | ≥ 20 | | Node.js | ≥ 20 |
| Docker & Compose| ≥ 24 | | Docker & Compose| ≥ 24 |
| PostgreSQL | 16 (or use Docker) | | PostgreSQL | 16 |
| Redis | 7 (or use Docker) | | Redis | 7 |
| Helm | ≥ 3.12 |
### 1. Clone & Install ### 1. Clone & Install
```bash ```bash
git clone <repo-url> host && cd host git clone <repo-url> host && cd host
# Backend
cd backend && npm install && cd .. cd backend && npm install && cd ..
# Frontend
cd frontend && npm install && cd .. cd frontend && npm install && cd ..
``` ```
### 2. Environment Variables ### 2. Environment Variables
```bash ```bash
# Backend
cp backend/.env.example backend/.env 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 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 ```bash
docker compose up --build docker compose up --build
``` ```
This spins up **PostgreSQL**, **Redis**, **Backend** (port 4000), and **Frontend** (port 3000). Backend at port 4000, Frontend at port 3000.
Open [http://localhost:3000](http://localhost:3000) in your browser.
### 4. Run Locally (development) ### 4. Run Locally (development)
```bash ```bash
# Terminal 1 — Backend # Terminal 1 — Backend
cd backend cd backend && npm run start:dev
npm run start:dev
# Terminal 2 — Frontend # Terminal 2 — Frontend
cd frontend cd frontend && npm run dev
npm run dev
``` ```
--- ---
## API Endpoints ## API Endpoints
All endpoints are prefixed with `/api/v1`. All endpoints prefixed with `/api/v1`. Full Swagger docs at `http://localhost:4000/docs`.
### Auth ### Auth
| Method | Path | Description | | Method | Path | Description |
| ------ | ----------------- | ------------------- | |--------|------|-------------|
| POST | /auth/register | Create account | | POST | /auth/register | Create account |
| POST | /auth/login | Get JWT tokens | | POST | /auth/login | Get JWT tokens |
| POST | /auth/refresh | Refresh access token| | POST | /auth/refresh | Refresh access token |
### Applications ### Applications
| Method | Path | Description | | Method | Path | Description |
| ------ | ------------------ | ------------------- | |--------|------|-------------|
| POST | /applications | Create app | | POST | /applications | Create app |
| GET | /applications | List user's apps | | GET | /applications | List user's apps |
| GET | /applications/:id | Get app details | | GET | /applications/:id | App details |
| PATCH | /applications/:id | Update app | | PATCH | /applications/:id | Update app |
| DELETE | /applications/:id | Delete app | | DELETE | /applications/:id | Delete app + K8s resources |
### Deployments ### Deployments
| Method | Path | Description | | Method | Path | Description |
| ------ | ------------------------------------ | -------------------- | |--------|------|-------------|
| POST | /applications/:appId/deployments | Trigger deploy | | POST | /applications/:appId/deployments | Trigger deploy |
| GET | /applications/:appId/deployments | List deployments | | GET | /applications/:appId/deployments | List deployments |
| GET | /deployments/:id | Deployment detail | | GET | /deployments/:id | Deployment detail |
| GET | /deployments/:id/logs | Get pod logs | | GET | /deployments/:id/logs | Pod logs |
| POST | /deployments/:id/stop | Stop deployment | | POST | /deployments/:id/stop | Stop deployment |
| POST | /deployments/:id/restart | Restart deployment | | POST | /deployments/:id/restart | Restart deployment |
### Users (authenticated) ### Billing
| Method | Path | Description | | Method | Path | Description |
| ------ | ---------- | ---------------- | |--------|------|-------------|
| GET | /users/me | Current user | | GET | /billing/balance | Get wallet balance |
| PATCH | /users/me | Update profile | | 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 ### Admin — Users
| Method | Path | Description | | Method | Path | Description |
| ------ | ------------------------------ | ------------------ | |--------|------|-------------|
| GET | /users | List all users | | GET | /users | List all users |
| PATCH | /users/:id/activate | Activate user | | PATCH | /users/:id/activate | Activate user |
| PATCH | /users/:id/deactivate | Deactivate user | | PATCH | /users/:id/deactivate | Deactivate user |
| PATCH | /users/:id/role | Change role | | PATCH | /users/:id/role | Change role |
### Admin — Clusters ### Admin — Clusters
| Method | Path | Description | | Method | Path | Description |
| ------ | --------------- | ----------------- | |--------|------|-------------|
| POST | /clusters | Add cluster | | POST | /clusters | Add cluster |
| GET | /clusters | List clusters | | GET | /clusters | List clusters |
| GET | /clusters/:id | Cluster details | | GET | /clusters/:id | Cluster details |
| PATCH | /clusters/:id | Update cluster | | PATCH | /clusters/:id | Update cluster |
| DELETE | /clusters/:id | Remove cluster | | DELETE | /clusters/:id | Remove cluster |
> 📖 Full Swagger docs available at `http://localhost:4000/docs` when the backend is running.
--- ---
## Deployment Flow ## Configuration
``` | Variable | Description | Default |
Developer creates app → Uploads code / provides Git URL |----------|-------------|---------|
| `PORT` | Backend port | `4000` |
| `DB_HOST` | PostgreSQL host | `localhost` |
Build Service creates Kaniko Job in K8s | `DB_PORT` | PostgreSQL port | `5432` |
| `DB_USERNAME` | Database user | `cloudhost` |
| `DB_PASSWORD` | Database password | — |
Kaniko builds Docker image → Pushes to Container Registry | `DB_NAME` | Database name | `cloudhost` |
| `JWT_SECRET` | JWT signing secret | — |
| `JWT_EXPIRES_IN` | Access token TTL | `15m` |
Kubernetes Service generates manifests from Handlebars templates: | `REDIS_HOST` | Redis host | `localhost` |
• Namespace • Deployment • Service • Ingress | `REDIS_PORT` | Redis port | `6379` |
• Database (optional) • PVC • Secret | `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` |
Applies manifests to target cluster via @kubernetes/client-node | `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) |
App is live at https://<subdomain>.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 |
--- ---
@@ -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 ## License
MIT MIT