keyhan 1529bf0d46 fix(invoices): render PDF in isolated iframe to avoid oklch crash
html2canvas 1.x cannot parse Tailwind v4's oklch() colors, so generating the
invoice PDF from the live document threw and the download silently failed.
Render the invoice template inside a sandboxed iframe that loads only the Peyda
@font-face and no app stylesheets, so the captured tree is free of oklch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:10:10 +03:30
2026-04-05 15:22:01 +03:30

☁️ 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 16  │  REST   │   NestJS API     │  K8s   │  Kubernetes  │
│  Frontend    │◄───────►│   Backend        │◄──────►│  Cluster(s)  │
└─────────────┘          └────────┬────────┘        └──────────────┘
                                  │
                       ┌──────────┼──────────┐
                       ▼          ▼          ▼
                  PostgreSQL    Redis     Container
                                (Bull)    Registry
Layer Technology
Frontend Next.js 16, Tailwind CSS v4, React Query, Zustand
Backend API NestJS 11, 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. 🔼 See UPGRADE.en.md (فارسی) for the latest dependency-upgrade notes (React 19, Next 16, NestJS 11, Tailwind 4, k8s-client v1).


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-platform/  # Helm chart (control plane)
│   │   └── cloudhost-app/       # Helm chart (user apps)
│   │       ├── 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. Deploy Platform on Kubernetes (Helm)

Prerequisites: NGINX Ingress, cert-manager (if TLS enabled), StorageClass for PVCs.

# Build images (set API URL to match ingress.api.host when TLS is on)
export REG=your-registry.example.com
docker build -t $REG/cloudhost-backend:latest ./backend
docker build -t $REG/cloudhost-frontend:latest \
  --build-arg NEXT_PUBLIC_API_URL=https://api.platform.example.com ./frontend
docker push $REG/cloudhost-backend:latest $REG/cloudhost-frontend:latest

# Install (copy and edit values-production.example.yaml first)
helm upgrade --install cloudhost ./backend/helm/cloudhost-platform \
  -n cloudhost --create-namespace \
  -f backend/helm/cloudhost-platform/values-production.example.yaml

Key values: ingress.enabled, ingress.tls.enabled, ingress.frontend.host, ingress.api.host, postgres.password, secrets.jwtSecret.

See chart defaults in backend/helm/cloudhost-platform/values.yaml and post-install notes via helm get notes cloudhost -n cloudhost.

5. 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 validationclass-validator on all DTOs

License

MIT

S
Description
No description provided
Readme MIT 3.2 MiB
Languages
TypeScript 96.3%
HTML 1.2%
Shell 0.7%
Go Template 0.5%
CSS 0.5%
Other 0.7%