Why We Chose Kubernetes for WordPress Hosting
When we started building UnionStack, we had a choice: traditional LAMP stack on VMs, managed WordPress platforms (WP Engine, Kinsta), or Kubernetes. We chose Kubernetes. Here's why, the trade-offs we accepted, and what we learned after running 2,800+ WordPress sites in production.
The Problem We Were Solving
We needed to build a WordPress platform that could:
- Isolate resources per site: No noisy neighbor problem—one site's traffic spike shouldn't affect others
- Scale independently: Each site should scale CPU/RAM based on its own traffic, not shared pool limits
- Deploy in minutes: Provisioning a new WordPress site should take 5 minutes, not 2 hours
- Update safely: Test WordPress core updates before applying them to production
- Run anywhere: Not locked into AWS/GCP pricing—should run on Hetzner, OVH, bare metal
Traditional shared hosting fails all five requirements. Managed WordPress platforms (WP Engine, Kinsta) solve 1-3 but are expensive (€25-100/month per site) and still tied to cloud provider pricing. Kubernetes solves all five—but at the cost of operational complexity.
Alternatives We Considered
1. Traditional LAMP Stack (Apache/nginx + MySQL + PHP-FPM)
The classic approach: rent 10 VMs, install Apache, MySQL, PHP-FPM, and manually configure virtual hosts for each WordPress site.
Pros:
- Simple to understand—every sysadmin knows LAMP
- Mature tooling (cPanel, Plesk, ISPConfig)
- No abstraction layers—direct control over every config file
Cons (deal-breakers):
- No resource isolation: 200+ sites share the same Apache process pool and MySQL server
- Manual scaling: Traffic spike? SSH into the VM, edit php-fpm config, restart services
- Slow provisioning: Creating a new site takes 20-30 minutes (manual DB creation, vhost config, SSL setup)
- No orchestration: Updates, backups, monitoring all require custom scripts
We tested this approach on Hetzner VMs (CX51: 8 vCPU, 32GB RAM, €30/month). Result: 50-80 WordPress sites per VM before PHP-FPM worker exhaustion. TTFB climbed to 800-1200ms under load. This doesn't scale to thousands of sites without massive manual operations overhead.
2. Managed WordPress Platforms (WP Engine, Kinsta, Flywheel)
The premium option: let someone else handle infrastructure, pay €25-100/month per site, get great performance and support.
Pros:
- Excellent performance (200-400ms TTFB typical)
- Automated backups, security, updates
- Expert support team
- Fast provisioning (5-10 minutes)
Cons (deal-breakers):
- Prohibitive cost: €25-100/month × 2,847 sites = €71,175-284,700/month
- Locked into cloud pricing: WP Engine runs on AWS/GCP—you pay their markup on top of cloud costs
- Inflexible infrastructure: Can't run on Hetzner bare metal or custom hardware
- Not white-label friendly: Branded login screens, support portals
This model works if you're hosting 10-50 high-value sites (€500+ each). For a platform hosting thousands of sites at €7-50/month, the economics don't work. We'd lose money on every customer.
3. Docker Compose on VMs
A middle ground: use Docker for isolation, run multiple containers per VM, orchestrate with Compose or Swarm.
Pros:
- Container isolation without Kubernetes complexity
- Resource limits per container (CPU/RAM quotas)
- Portable—runs anywhere Docker does
Cons (limitations):
- No multi-node orchestration: Docker Compose is single-host only
- Manual load balancing: Traefik/Caddy config per container
- No self-healing: If a container crashes, it stays down until you restart it
- Scaling requires custom tooling: No built-in horizontal autoscaling
We prototyped this approach. Verdict: works for 100-200 sites, but managing 2,000+ containers across 20+ VMs without orchestration is a nightmare. Configuration drift, manual intervention on failures, no declarative state management.
Why Kubernetes Won
Kubernetes solves the orchestration problem. It's not the easiest option, but it's the only option that met all five requirements.
1. Resource Isolation via Namespaces + Pods
Every WordPress site runs in its own pod with dedicated resources. No shared PHP-FPM pool. Example pod spec:
apiVersion: v1
kind: Pod
metadata:
name: example-site
namespace: example-site-ns
spec:
containers:
- name: wordpress
image: wordpress:6.5-php8.2-fpm
resources:
requests:
cpu: "1000m" # 1 CPU core guaranteed
memory: "1Gi" # 1GB RAM guaranteed
limits:
cpu: "2000m" # Can burst to 2 cores
memory: "2Gi" # Hard limit at 2GBIf one site's traffic spikes to 100% CPU, it hits its limit and gets throttled—but other sites are unaffected. This is impossible with shared Apache/PHP-FPM on a VM.
2. Declarative Configuration (Infrastructure as Code)
Kubernetes uses YAML manifests to declare the desired state of your infrastructure. Example: "I want 3 replicas of this WordPress pod running at all times." Kubernetes ensures this state is maintained—if a pod crashes, it's automatically recreated.
Contrast with traditional approach: write a Bash script to start 3 Apache processes, hope they don't crash, manually restart if they do.
3. Self-Healing and High Availability
Kubernetes monitors pod health via liveness and readiness probes. If a WordPress pod becomes unresponsive (PHP-FPM hangs, OOM kill), Kubernetes detects this and restarts the pod automatically—typically within 10-30 seconds.
Real-world example: On January 15, 2026, a WordPress plugin (WP Rocket 3.15.2) had a memory leak bug that caused PHP-FPM processes to consume 4GB+ RAM over 48 hours. 127 pods hit OOM kills. Kubernetes detected the pod failures and restarted them automatically. Total downtime per site: ~15 seconds. Zero manual intervention required.
4. Horizontal Scaling with Bitpoke WordPress Operator
We use the Bitpoke WordPress Operator (formerly Presslabs), an open-source Kubernetes operator that manages WordPress lifecycle. It handles:
- Auto-provisioning: Create a WordPress CRD (Custom Resource Definition), operator provisions pods, services, ingress, SSL certs
- Database management: Automatic MySQL user creation, password rotation, connection pooling
- Object caching: Memcached sidecar automatically injected into WordPress pods
- Backup scheduling: Daily snapshots to S3-compatible storage (Hetzner Object Storage)
Creating a new WordPress site is a single YAML manifest:
apiVersion: wordpress.presslabs.org/v1alpha1
kind: WordPress
metadata:
name: example-site
namespace: example-site-ns
spec:
replicas: 1
image: wordpress:6.5-php8.2-fpm
domains:
- example.com
code:
contentSubPath: wp-content
database:
host: mysql.default.svc.cluster.local
name: wp_example
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"Apply this manifest with kubectl apply -f, and within 5 minutes you have a production-ready WordPress site with SSL, object caching, and automatic backups.
5. Cloud-Agnostic Infrastructure
Kubernetes runs anywhere: AWS, GCP, Azure, Hetzner, OVH, bare metal. We run on Hetzner Cloud (Falkenstein, Germany) because:
- 60% cheaper: Hetzner CX51 (8 vCPU, 32GB RAM) = €30/month. AWS c5.2xlarge (8 vCPU, 16GB RAM) = €180/month
- NVMe SSDs: Local direct-attached storage (4000 IOPS sustained)
- 10 Gbps networking: Low-latency east-west traffic between nodes
- EU data residency: Falkenstein, Germany (GDPR compliant)
If Hetzner pricing changes or we need to migrate to another provider, we can redeploy the entire Kubernetes cluster on a new cloud in 2-3 hours. Same YAML manifests, same infrastructure.
The Trade-Offs We Accepted
Kubernetes is not free complexity. Here's what we had to build to make it work:
1. Steep Learning Curve
It took 3 months to go from "Kubernetes beginner" to "production-ready cluster." Key concepts to master:
- Pods, Deployments, StatefulSets, DaemonSets: Different workload types for different use cases
- Services, Ingress, Network Policies: Networking and traffic routing
- Volumes, PersistentVolumeClaims, StorageClasses: Persistent storage for databases and uploads
- RBAC, ServiceAccounts, Secrets: Security and access control
- Operators, CRDs, Helm: Extending Kubernetes with custom resources
If you're a solo developer or small team, this is a significant investment. You'll spend weeks just understanding how the pieces fit together.
2. Monitoring and Observability Stack
Kubernetes doesn't include monitoring out-of-the-box. We had to deploy:
- Prometheus: Metrics collection (CPU, RAM, disk, network per pod)
- Grafana: Dashboards and visualization
- Alertmanager: Alerting rules (e.g., "pod restart count > 10 in 1 hour")
- Loki: Log aggregation (centralized logs from 2,800+ pods)
Total overhead: ~8GB RAM and 2 CPU cores for the monitoring stack itself.
3. Backup and Disaster Recovery
Kubernetes doesn't solve backups. We built:
- Velero: Kubernetes-native backup tool for cluster state (YAML manifests, etcd snapshots)
- Custom backup jobs: Daily MySQL snapshots + wp-content uploads to Hetzner Object Storage (S3-compatible)
- Restore testing: Monthly disaster recovery drills (restore random site from backup, verify)
4. Cold Start Time
Provisioning a new WordPress site takes 5 minutes, not instant. Why?
- Kubernetes creates pod (10-15 seconds)
- WordPress operator creates MySQL database (20-30 seconds)
- WordPress init container downloads wp-content from backup (30-60 seconds)
- Cert-manager requests Let's Encrypt SSL certificate (60-90 seconds)
- Traefik ingress controller updates routes (10-20 seconds)
Total: 2.5-4 minutes on average. Contrast with managed platforms (WP Engine: 10-15 minutes) or VMs (30+ minutes manual setup). Still fast, but not instant.
Lessons Learned After 2 Years in Production
1. Use Managed Kubernetes (k3s) If Possible
We started with a custom kubeadm cluster (self-managed control plane, etcd, networking). This was a mistake. Too much operational overhead. We migrated to k3s (Rancher's lightweight Kubernetes distribution):
- Single binary: No separate etcd, apiserver, controller-manager binaries
- Embedded datastore: SQLite instead of etcd (simpler, fewer moving parts)
- Optimized for edge/bare metal: ARM64 support, low resource overhead (512MB RAM for control plane)
If you're on AWS/GCP/Azure, use EKS/GKE/AKS. If you're on Hetzner/OVH/bare metal, use k3s. Don't self-manage control planes unless you have a dedicated Kubernetes team.
2. Invest in Observability Early
We went 6 months without proper monitoring. Big mistake. When a site went down, we had no visibility into why. Now we track:
- Golden signals: Latency (TTFB p50/p95/p99), traffic (req/s), errors (4xx/5xx rate), saturation (CPU/RAM %)
- Pod health: Restart count, OOM kills, readiness/liveness probe failures
- Database metrics: Query latency, connection pool exhaustion, slow query count
This visibility caught 90% of issues before customers reported them.
3. Start with Stateless Workloads
WordPress is stateful (uploads, database). This is hard in Kubernetes. If you're learning Kubernetes, start with stateless apps (APIs, frontends) before tackling stateful workloads.
Key challenge: persistent storage. WordPress uploads live in wp-content/uploads. If the pod is rescheduled to a different node, uploads must follow. Solutions:
- PersistentVolumes (PVs): Network-attached storage (Hetzner Volumes, EBS, Ceph)
- Object storage (S3): Offload uploads to S3-compatible storage via plugins (WP Offload Media)
We use PVs for wp-content and S3 for large uploads (videos, PDFs).
Would We Choose Kubernetes Again?
Yes. Despite the complexity, Kubernetes delivers on its promises:
- 122ms median TTFB: Resource isolation + optimized pod specs
- 99.7% uptime: Self-healing pods, automatic restarts, zero-downtime rolling updates
- €0.016/site update cost: Ephemeral test pods enable safe WordPress updates
- 5-minute provisioning: Declarative infrastructure beats manual VM configuration
The upfront investment (3 months learning, custom tooling, monitoring stack) pays dividends at scale. We now manage 2,800+ sites with a 3-person ops team. That's ~930 sites per ops person. Traditional LAMP hosting achieves 100-200 sites per ops person.
Conclusion: When to Choose Kubernetes
Choose Kubernetes if:
- You're building a platform hosting 100+ sites (economies of scale justify complexity)
- You need resource isolation and independent scaling per site
- You want infrastructure portability (cloud-agnostic)
- You have 6-12 months to invest in learning and tooling
Don't choose Kubernetes if:
- You're hosting 1-10 sites (managed WordPress or VMs are simpler)
- You're a solo developer with no Kubernetes experience (use managed platforms)
- You need same-day production deployment (learning curve is too steep)
Experience Kubernetes-powered WordPress hosting without the complexity.
Deploy your WordPress site on UnionStack. We handle the Kubernetes infrastructure—you get the performance benefits without the operational overhead.
Get Started →Published February 9, 2026. Architecture insights based on 2 years operating 2,800+ WordPress sites on Kubernetes 1.28+ (k3s distribution). Infrastructure: Hetzner Cloud (Falkenstein, Germany), Bitpoke WordPress Operator v0.12.4.