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:
@@ -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 <repo-url> 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://<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 |
|
||||
| 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
|
||||
|
||||
Reference in New Issue
Block a user