Skip to main content

Tenant Services

Tenant services are the microservices that power each tenant's business operations. Every tenant gets fully isolated instances of these services running in their own Kubernetes namespace with dedicated databases, queues, cache, and storage.

Architecture

┌─────────────────────────────────────────────────────────┐
│ Tenant Namespace │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ Webshop │ │Warehouse │ │ CRM │ │Frontend│ │
│ │ :8010 │ │ :8011 │ │ :8012 │ │ :5175 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────────┘ │
│ │ │ │ │
│ ┌────┴─────┐ ┌─────┴────┐ ┌─────┴────┐ │
│ │ Webhook │ │Analytics │ │WS Proxy │ │
│ │ :8013 │ │ :8014 │ │ :8015 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────▼──────────────▼──────────────▼─────────────────┐ │
│ │ Shared Tenant Infrastructure │ │
│ │ PostgreSQL DB │ RabbitMQ vhost │ Redis │ S3 │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

Service Overview

ServicePurposeTech StackPort (dev)
WebshopProduct catalog, orders, cart, paymentsLaravel 12, PostgreSQL8010
WarehouseInventory management, stock transfersLaravel 12, PostgreSQL8011
CRMCustomer data, email campaigns, contactsLaravel 12, PostgreSQL8012
WebhookExternal integrations, event deliveryLaravel 12, RabbitMQ8013
AnalyticsBusiness intelligence, dashboards, reportsLaravel 12, PostgreSQL8014
WebSocket ProxyReal-time events, live notificationsLaravel 12, WebSockets8015
Tenant FrontendUnified Vue 3 SPA for all servicesVue 3, TypeScript5175

Isolation Model

Each tenant namespace contains:

  • Dedicated PostgreSQL database — Created by credential-generator at first deploy
  • RabbitMQ virtual host — Isolated message routing per tenant
  • Redis instance — Password-protected, per-namespace cache and sessions
  • S3 buckets — Private and public object storage via Rook-Ceph
  • Kubernetes secrets — Auto-generated credentials for all services

Inter-Service Communication

Services communicate through two patterns:

Synchronous (HTTP)

Direct REST API calls between services within the same namespace:

Webshop → Warehouse (stock check)
Webshop → CRM (customer lookup)
Frontend → All backends (API calls)

Asynchronous (RabbitMQ)

Event-driven messaging for decoupled operations:

Webshop → [order.created] → Warehouse (reserve stock)
Webshop → [order.created] → Analytics (record sale)
CRM → [customer.updated] → Webhook (notify external)

Deployment

All tenant services are deployed through the GitOps pipeline. The DevOps API generates Kubernetes manifests from a template for each new tenant.

Sync Wave Order

WaveResources
-2Namespace
-1Credential generator, RBAC, image versions
0PostgreSQL database init, S3 credentials sync
1All service deployments and services
2Ingress routes, certificates, CronJobs
3Redis

Scaling

KEDA (Kubernetes Event-Driven Autoscaling) manages tenant workloads:

  • Idle tenants scale to zero replicas (no resource consumption)
  • Active tenants scale up automatically based on HTTP traffic or queue depth
  • Minimum 1 replica when traffic is detected, maximum configurable per tenant plan

Development

# Start all tenant services
cd vecton/init
make dev-tenant

# Or specific services
cd vecton/tenant
make dev-webshop
make dev-frontend

Each backend service runs as a standard Laravel application:

cd tenant/tenant-backend-webshop
php artisan serve --port=8010