695e05f948cdad398a2dcd9f8cf3a0e925ab065b
Introduce product types for managed PostgreSQL, Redis, and RabbitMQ with a dedicated dashboard, Helm-only deploy pipeline, external access, snapshots with progress, and prorated resource or storage upgrades matching application billing rules. PVCs use an expandable StorageClass with automatic migration when legacy disks cannot resize in place. Co-authored-by: Cursor <cursoragent@cursor.com>
☁️ CloudHost — Self-Service PaaS Platform
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.
Architecture Overview
┌─────────────┐ ┌─────────────────┐ ┌──────────────┐
│ Next.js 14 │ REST │ NestJS API │ K8s │ Kubernetes │
│ Frontend │◄───────►│ Backend │◄──────►│ Cluster(s) │
└─────────────┘ └────────┬────────┘ └──────────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
PostgreSQL Redis Container
(Bull) Registry
| Layer | Technology |
|---|---|
| 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) |
| Deployment | Helm v3 charts, @kubernetes/client-node |
| Database | PostgreSQL 16 |
| Queue | Redis 7 + BullMQ |
📖 See ARCHITECTURE.md for detailed system design.
Features
For Developers
- 🚀 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
Project Structure
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
│ │ ├── auth/ # JWT auth (register, login, refresh)
│ │ ├── users/ # User CRUD + admin ops
│ │ ├── applications/ # Application CRUD + code upload
│ │ ├── deployments/ # Deployment pipeline orchestration
│ │ ├── clusters/ # Cluster management (admin)
│ │ ├── 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/ # Legacy Handlebars templates (deprecated)
│
├── 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
Quick Start
Prerequisites
| Tool | Version |
|---|---|
| Node.js | ≥ 20 |
| Docker & Compose | ≥ 24 |
| PostgreSQL | 16 |
| Redis | 7 |
| Helm | ≥ 3.12 |
1. Clone & Install
git clone <repo-url> host && cd host
cd backend && npm install && cd ..
cd frontend && npm install && cd ..
2. Environment Variables
cp backend/.env.example backend/.env
cp frontend/.env.local.example frontend/.env.local
# Edit both files with your DB, JWT, Redis, and registry settings
3. Run with Docker Compose
docker compose up --build
Backend at port 4000, Frontend at port 3000.
4. Run Locally (development)
# Terminal 1 — Backend
cd backend && npm run start:dev
# Terminal 2 — Frontend
cd frontend && npm run dev
API Endpoints
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 |
Applications
| 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 | Pod logs |
| POST | /deployments/:id/stop | Stop deployment |
| POST | /deployments/:id/restart | Restart deployment |
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 |
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 |
Configuration
| 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) |
Security
- JWT access + refresh tokens with configurable expiry
- Bcrypt password hashing (12 rounds)
- Helmet HTTP security headers
- RBAC role-based route guards (
@Roles(UserRole.ADMIN)) - Namespace isolation — each user deploys to their own K8s namespace
- Secrets — env vars stored as K8s Secrets, never in plain manifests
- Input validation —
class-validatoron all DTOs
License
MIT
Languages
TypeScript
96.3%
HTML
1.2%
Shell
0.7%
Go Template
0.5%
CSS
0.5%
Other
0.7%