Apr 16, 2026
System

How I built Kumix Cloud – A Modern VPS Management Platform

TL;DR: Kumix.cloud is a multi-tenant SaaS dashboard built with Laravel and React that lets DevOps engineers, system administrators, and hosting providers manage VPS instances, SSH credentials, and server health from a single, real-time interface. Here’s how I built it.

The Problem

Managing multiple VPS servers across different providers is a fragmented nightmare. You bounce between:

  • Provider dashboards (DigitalOcean, Vultr, Linode)
  • SSH terminals for testing connections
  • Spreadsheets tracking SSL certificate expiration dates
  • Multiple SSH key backups and management tools

I needed one place to:

  • Store and manage SSH keys securely
  • Monitor server health in real-time
  • Track SSL certificate expiration
  • Test SSH connectivity instantly
  • Scale to hundreds of servers without breaking a sweat

Most existing solutions were either bloated enterprise tools or bare-bones CLIs. I wanted something in between: powerful, intuitive, and cloud-native.

Architecture: Multi-Tenant SaaS from Day One

I designed Kumix.cloud as a multi-tenant platform from the ground up. This wasn’t just about supporting multiple users—it was about building the right foundation.

Core Principles

1. Security First

  • SSH keys encrypted with AES-256 at rest
  • Laravel Policies for granular authorization
  • Every API endpoint enforces user ownership
  • Rate limiting to prevent abuse

2. Real-Time Updates

  • WebSocket broadcasts for instant metric updates
  • Async job processing via queue workers
  • No polling, no stale data
  • Event-driven architecture

3. Modular & Scalable

  • Nwidart Laravel Modules for feature isolation
  • Service layer for business logic
  • Clear separation of concerns
  • Ready for horizontal scaling

Tech Stack Decision Making

LayerTechnologyWhy
BackendLaravel 12Mature ecosystem, excellent security, built-in policies, WebSocket support
FrontendReact 19 + Inertia.jsServer-side rendering benefits + React flexibility without API complexity
UI ComponentsShadcn/UI + TailwindCSSAccessible, customizable, consistent design system
SSH Libraryphpseclib3Pure PHP, no external SSH dependencies, secure
Real-TimeLaravel ReverbBuilt into Laravel 12, Pusher alternative, self-hostable
DatabasePostgreSQLJSONB support, better for metrics, superior performance
QueueRedisFast, reliable, supports retries and prioritization

Building the VPS Module

I used Laravel Modules (nwidart) to organize features into cohesive packages. The VPS module became the heart of the application.

Database Design: 8 Core Tables

ssh_keys          → Encrypted credential storage
servers           → VPS instance management
services          → Application/service tracking per server
domains           → Domain records and DNS
ssl_certs         → Certificate lifecycle management
job_logs          → Audit trail for async operations
billing_plans     → Plan tiers and quotas
server_metrics    → CPU, memory, disk, network metrics

Each table was designed with multi-tenant isolation in mind. Every resource except billing_plans has a user_id foreign key.

The SSH Challenge

Managing SSH keys was the trickiest part. Users needed:

  • Secure storage (encrypted at rest)
  • Support for RSA, ECDSA, and Ed25519 keys
  • Quick validation without exposing private keys
  • Easy import/export

Solution: Built SSHKeyService with:

// Encryption on store
$encrypted = Crypt::encryptString($privateKey);

// Decryption for operations
$decrypted = Crypt::decryptString($encrypted);

// Fingerprint validation (public key reference)
$fingerprint = hash('sha256', $publicKey);

This let me:

  • Store encrypted keys securely
  • Validate key format before storing
  • Use fingerprints for quick identity checks
  • Keep private keys away from logs and outputs

Async SSH Testing with WebSockets

Testing SSH connection directly in a controller? That’s a timeout waiting to happen.

I built TestConnectionJob for background processing:

  1. User clicks “Test Connection”
  2. Job is queued with server ID and timeout
  3. Controller returns immediately with job ID
  4. Job executes SSH test via phpseclib3
  5. Result broadcasts via WebSocket to frontend
  6. Frontend receives update, shows success/failure

This pattern became foundational: queue jobs for long-running operations, broadcast results in real-time.

Real-Time Metrics Dashboard

The dashboard needed to show live metrics without polling. I implemented:

Broadcasting Channel Authorization:

Broadcast::channel('server-metrics.{serverId}', function ($user, $serverId) {
    $server = Server::find($serverId);
    return $server && $user->can('view', $server);
});

Event Broadcasting:

public function broadcastOn(): Channel
{
    return new PrivateChannel("server-metrics.{$this->server->id}");
}

Frontend listens to these channels via Laravel Echo, updating metrics instantly as they arrive.

Frontend: React + Inertia.js

I chose Inertia.js over a pure API approach because:

Pros:

  • Less boilerplate than typical REST API + SPA
  • Share Laravel data models directly in React
  • No session/auth token complexity
  • Type-safe route generation
  • Server-side pagination/filtering built-in

Pages Implemented:

  1. Dashboard: Real-time server overview, status indicators, certificate alerts
  2. Servers: Full CRUD with filtering, bulk operations, status monitoring
  3. SSH Keys: Key management, import/export, fingerprint validation
  4. Services: Per-server application monitoring
  5. Domains: Domain tracking with DNS provider integration
  6. SSL Certificates: Lifecycle management, expiration alerts
  7. Billing: Plan selection and usage tracking

Each page used Shadcn/UI components for consistency. The design system gave us free accessibility (Radix UI) and dark mode support.

Key Implementation Challenges

Challenge 1: Multi-Tenant Data Isolation

Problem: A query mishap could leak server data between users.

Solution: Implemented on three levels:

// 1. Model Scope (automatic filtering)
public function scopeVisible(Builder $query)
{
    return $query->where('user_id', auth()->id());
}

// 2. Policy Authorization (gate-check)
public function view(User $user, Server $server)
{
    return $user->id === $server->user_id;
}

// 3. Channel Authorization (real-time access)
Broadcast::channel('server-metrics.{serverId}', function ($user, $serverId) {
    return auth()->user()->can('view', Server::find($serverId));
});

No query escapes without checking user ownership.

Challenge 2: Encryption Key Management

Encrypting SSH keys sounds simple until you realize:

  • Need same key for all users (can’t use per-user keys)
  • Key rotation is complex
  • Secrets can leak in logs

Solution:

  • Used Laravel’s built-in Crypt facade (APP_KEY)
  • Keys stay in .env, never in code
  • All decryption operations sanitize error messages
  • Implemented separate encryption for highly sensitive data

Challenge 3: Real-Time Broadcasting at Scale

Broadcasting to thousands of concurrent users seemed expensive.

Optimization:

  • Private channels (only users who own the server receive updates)
  • Throttled broadcasts (send metrics every 30s, not every 1s)
  • Efficient database queries for metric aggregation
  • Redis for fast channel lookup

Challenge 4: SSH Connection Pooling

Thousands of SSH connections would exhaust resources.

Approach:

  • phpseclib3 handles connection lifecycle
  • Connections created on-demand, destroyed after use
  • No persistent pool (tested, not needed)
  • Rate limiting prevents connection storms

Development Workflow

I followed a disciplined workflow to keep code quality high:

1. Planning

Before coding, I created detailed plans:

  • Component relationships
  • API endpoint specifications
  • Database schema design
  • Security checklist

2. Implementation

  • Write service layer first (business logic isolated)
  • Build controllers (thin, focused)
  • Create React components (consume controllers via Inertia)
  • Write tests concurrently

3. Quality Checks

  • Type checking (TypeScript frontend, Laravel types)
  • Linting (ESLint, Pint)
  • Tests for critical paths (auth, multi-tenant isolation)
  • Manual testing in browser

4. Git Discipline

Every commit follows conventional commits:

feat: add ssh key fingerprint validation
fix: prevent metric query from leaking other users' data
refactor: extract SSHConnectionService
test: add policy authorization tests

Lessons Learned

1. Laravel Policies are Powerful

Policies became my primary security layer. Every authorization check went through them. This single decision prevented countless security bugs.

2. Async First

The moment I built TestConnectionJob, I started thinking “should this be async?” for any I/O operation. It became the default pattern.

3. WebSockets Beat Polling

Even simple metric polling felt clunky. WebSocket events made the dashboard feel alive. One real-time broadcast beats 100 poll requests.

4. Modular Architecture Scales

The Nwidart module approach let me add features (new controllers, models, migrations) without touching the core. By Phase 2, adding Vultr integration was just a new module.

5. Design Systems Matter

Using Shadcn/UI + TailwindCSS from day one meant I never had inconsistent buttons or missing dark mode. Design systems are force multipliers.

6. Monitoring Matters

The job_logs table tracking every async operation saved hours of debugging. “When did this SSH test run?” was always answerable.

Feature Highlights

Feature 1: One-Click SSH Testing

User clicks "Test" → Job queued → SSH test runs → WebSocket broadcasts result

No manual SSH commands, no connection strings, instant feedback.

Feature 2: Encrypted Key Storage

SSH keys encrypted at rest with AES-256. Fingerprints allow quick validation without exposing private keys.

Feature 3: Real-Time Metrics Dashboard

CPU, memory, disk usage updated live via WebSocket. No refresh needed.

Feature 4: Multi-Tenant Isolation

Each user sees only their servers. Policies enforce this at every layer.

Feature 5: Certificate Expiration Alerts

Dashboard highlights certificates expiring within 30 days. Never miss a renewal again.

Deployment & Operations

Development

composer dev  # Runs server, queue worker, Vite, log viewer concurrently

Production Considerations

  • Laravel Reverb for WebSocket broadcasting
  • Redis for queue and caching
  • PostgreSQL for database
  • Supervisor/systemd for queue workers
  • CloudFlare for CDN and DDoS protection

Monitoring

  • Job logs for audit trail
  • Server metrics history for trending
  • Error logs in storage/logs/
  • Health checks on SSH connectivity

Current State & Future

Phase 1 (Complete)

  • VPS server management 
  • SSH key management 
  • Real-time monitoring 
  • SSL certificate tracking 
  • Multi-tenant isolation 
  • Billing structure

Phase 2 (In Progress)

  • Vultr API integration for automated provisioning 
  • Service detection (Caddy, Fail2ban, WordPress)
  • Provider-agnostic deployment

Phase 3+ (Planned)

  • Advanced automation and playbooks 
  • Team collaboration and permissions 
  • Custom metrics and alerts 
  • Third-party integrations (monitoring, incident response)

Why This Matters

Kumix.cloud proves you don’t need a team of 10 to build enterprise-grade SaaS.

The right architecture decisions early (multi-tenant first, policies for security, async for I/O, WebSockets for real-time) meant adding features later was straightforward, not refactoring hell.

This is a production-ready platform built with:

  • Clean code principles (KISS, DRY, YAGNI)
  • Security as a first-class concern
  • Real-time user experience
  • Modular, scalable architecture

Technical Takeaways

For Backend Engineers:

  • Laravel Policies are underutilized but incredibly powerful
  • Async + Broadcasting beats polling for UX
  • Modular architecture enables rapid feature development

For Frontend Engineers:

  • Inertia.js eliminates API/SPA complexity without sacrificing control
  • Shadcn/UI + TailwindCSS create consistent, accessible interfaces
  • Real-time updates transform UX (WebSockets > polling)

For DevOps/Infrastructure:

  • Multi-tenant design baked in early prevents rewrites
  • Queue workers handle scale elegantly
  • PostgreSQL + Redis combo is battle-tested

For Startup Builders:

  • Ship MVP fast with Laravel + React
  • Invest in security and multi-tenant isolation early
  • One developer can build enterprise SaaS with the right tools

Tools I Used

  • Laravel – Backend framework
  • React – Frontend framework
  • Inertia.js – Server-side React rendering
  • Shadcn/UI – Component library
  • TailwindCSS – Styling
  • phpseclib3 – SSH library
  • PostgreSQL – Database
  • Redis – Caching and queues
  • Laravel Reverb – WebSocket broadcasting
  • Vite – Frontend build tool
  • TypeScript – Type safety

Conclusion

Building Kumix.cloud taught me that good architecture choices early compound into fast development later.

The decision to:

  • Use policies for security (not scattered middleware)
  • Broadcast events instead of polling
  • Build async-first for I/O operations
  • Design modular with nwidart modules

…meant that seven months later, I’m shipping Phase 2 features in days, not weeks.

If you’re building SaaS, the question isn’t “can one person do it?” It’s “are you willing to invest in architecture that scales with your ambitions?”

Kumix.cloud says yes.

What’s Next?

In Phase 2, I’m integrating with cloud provider APIs (Vultr, DigitalOcean) for automated provisioning. The architecture we built handles this with a new module; no core refactoring needed.

That’s the power of getting the foundations right.

Thanks for reading!