Architecture overview#
Understanding the architecture and design of cdk8s-plone deployments.
Overview#
cdk8s-plone provides CDK8S constructs for deploying Plone CMS on Kubernetes. The library handles all Kubernetes resources needed for a production-grade Plone deployment.
Key features#
Deployment variants#
cdk8s-plone supports two deployment variants:
Volto (React single-page frontend)
React-based frontend (Volto)
REST API backend (Plone)
Separate services for frontend and backend
Headless CMS architecture
Blicca (server-side rendered)
The Plone backend renders the UI and serves HTML directly
Single integrated service
Simpler deployment model
Blicca is the new name for the variant Plone formerly called “Classic UI”. Both approaches are equally current; they differ in where rendering happens, not in how modern they are.
High availability#
Replica Management
Configurable number of replicas for backend and frontend
Default: 2 replicas for each component
Supports horizontal scaling
Pod Disruption Budgets
Ensures minimum availability during cluster operations
Configurable
minAvailableandmaxUnavailablethresholdsProtects against voluntary disruptions (node drains, updates)
Health Probes
Readiness probes: Traffic routing only to healthy pods
Liveness probes: Automatic restart of unhealthy pods
Configurable delays, timeouts, and thresholds
HTTP caching layer#
Varnish Integration
Uses kube-httpcache Helm chart
Cluster-wide cache invalidation
HTTP/2 support
Configurable VCL
Prometheus metrics export
Benefits
Reduced backend load
Improved response times
Better scalability
Automatic cache invalidation on content changes
Caching options#
cdk8s-plone supports two HTTP caching approaches:
PloneHttpcache (mittwald/kube-httpcache)
Self-contained: deploys Varnish via Helm chart, no operator needed
Full VCL template with Go template variable injection
Prometheus exporter sidecar for metrics
PloneVinylCache (cloud-vinyl operator)
Operator-managed: creates a VinylCache custom resource
Structured VCL generation with snippet injection hooks
Built-in cache invalidation proxy (PURGE, BAN, xkey)
Agent-based VCL delivery and Prometheus metrics
Requires the cloud-vinyl operator in the cluster
Choose PloneHttpcache for standalone deployments without cloud-vinyl. Choose PloneVinylCache when the operator is available for centralized cache management.
Multi-language support#
The library is published in multiple languages:
TypeScript/JavaScript
Native CDK8S experience
Full TypeScript types
Published to npm:
@bluedynamics/cdk8s-plone
Python
JSII-generated Python bindings
Pythonic API
Published to PyPI:
cdk8s-plone
Architecture diagram#
graph TB
subgraph "External access"
Client[Client / Browser]
Ingress[Ingress Controller]
end
subgraph "Cache layer (optional)"
Varnish[Varnish<br/>PloneHttpcache or PloneVinylCache]
end
subgraph "Frontend (Volto variant only)"
FrontendSvc[Frontend Service]
Frontend1[Frontend Pod]
Frontend2[Frontend Pod]
end
subgraph "Backend (REST API for Volto, HTML for Blicca)"
BackendSvc[Backend Service]
Backend1[Backend Pod]
Backend2[Backend Pod]
end
subgraph "Data layer"
DB[(PostgreSQL<br/>with RelStorage)]
end
Client --> Ingress
Ingress --> Varnish
Varnish -.Volto: cache miss.-> FrontendSvc
Varnish -.Blicca: cache miss.-> BackendSvc
Varnish -.invalidation.-> BackendSvc
FrontendSvc --> Frontend1
FrontendSvc --> Frontend2
Frontend1 --> BackendSvc
Frontend2 --> BackendSvc
BackendSvc --> Backend1
BackendSvc --> Backend2
Backend1 --> DB
Backend2 --> DB
Component responsibilities#
Backend#
Responsibilities:
Plone REST API
Content management
ZODB with RelStorage (external database)
Search indexing
Workflow engine
Resources:
CPU: Compute-intensive operations (catalog queries, indexing)
Memory: ZODB cache, Python processes
Storage: Delegated to external database (PostgreSQL/MySQL/Oracle)
Scaling:
Horizontal: Add replicas for read scalability with RelStorage
Vertical: Increase resources for large catalogs
External database handles storage and multi-writer scenarios
Frontend (Volto)#
Responsibilities:
React single-page application
Server-side rendering (SSR)
API client
User interface
Resources:
CPU: SSR rendering, JavaScript execution
Memory: Node.js processes, SSR caching
Storage: Minimal (build artifacts only)
Scaling:
Horizontal: Add replicas for traffic handling
Vertical: Increase resources for SSR performance
No shared storage needed (stateless)
HTTP Cache (Varnish)#
Responsibilities:
HTTP caching
Cache invalidation
Request routing
Load distribution
Resources:
CPU: Request processing, cache lookup
Memory: Cache storage
Storage: Not required (in-memory cache)
Scaling:
Horizontal: Add replicas for cache distribution
Vertical: Increase memory for larger cache
Kubernetes resources created#
For a typical Volto deployment, cdk8s-plone creates:
Backend:
Deployment (backend pods)
Service (internal)
PodDisruptionBudget (optional)
ConfigMap (optional, for configuration)
Frontend:
Deployment (frontend pods)
Service (internal)
PodDisruptionBudget (optional)
HTTP Cache (optional):
StatefulSet (Varnish pods)
Service (entry point)
ConfigMap (VCL configuration)
Secret (admin credentials)
ServiceMonitor (optional, for Prometheus)
Design decisions#
CDK8S constructs#
Why CDK8S?
Type-safe infrastructure as code
Reusable components
Familiar programming languages
No templating required
IDE support and IntelliSense
Benefits:
Reduced boilerplate
Better error detection
Easier testing
Composition over configuration
Separate frontend and backend#
Volto Architecture:
Independent scaling of frontend and backend
Frontend can be restarted without affecting backend
Better resource utilization
Clear separation of concerns
When to use Blicca:
Simpler deployment model
Lower resource requirements
Legacy integrations
Specific add-on requirements
Optional Varnish layer#
Design Choice:
Varnish is optional, not mandatory
Uses established Helm chart (kube-httpcache)
Cluster-wide cache invalidation
Production-tested solution
Trade-offs:
Additional complexity
More resources required
Better performance at scale
Reduced backend load
Health probes#
Readiness Probe:
Enabled by default for backend
Prevents traffic to unready pods
Fast startup detection
Liveness Probe:
Disabled by default for backend (Plone is resilient)
Recommended enabled for frontend (detect SSR hangs)
Configurable thresholds
Production considerations#
Resource planning#
Backend:
Plan for catalog size and query complexity
ZODB cache size affects memory needs
Indexing operations are CPU-intensive
Frontend:
SSR requires CPU resources
Memory for Node.js processes
Scale based on traffic patterns
Cache:
Memory size determines cache capacity
Monitor hit rates and adjust sizing
High availability#
Recommendations:
Minimum 2 replicas per component
Configure PodDisruptionBudgets
Use node affinity for distribution
Enable health probes
Database:
External database required (PostgreSQL, MySQL, or Oracle)
Uses RelStorage for ZODB persistence
Enables true multi-writer deployments
Better backup and recovery options
MySQL derivatives (MariaDB, Percona) and Oracle are supported but untested
Monitoring#
Metrics to Track:
Pod resource usage (CPU, memory)
Request rates and latencies
Cache hit rates
Error rates
Health probe failures
Tools:
Prometheus for metrics collection
Grafana for visualization
Kubernetes events monitoring
See also#
Features — Feature overview and deployment variants.
Configuration guide — Complete configuration reference.
Quick start — Getting started tutorial.