What was running
The original setup was a classic LAMP stack on a single VPS — the kind of thing that powers roughly 40% of the internet. For a small security consultancy site it was perfectly adequate. Until it wasn't.
Apache 2.4 — web server, mod_rewrite for WordPress permalinks
WordPress 6.x — PHP application, OnePress theme
MySQL 8.0 — database on local socket, same machine
Let's Encrypt — SSL via certbot, auto-renewing
Wazuh agent — security monitoring
Single VPS — everything on one machine, one IP
What the site did
mfa2fa.com was a security consultancy portfolio covering four service areas:
IT Consultancy — infrastructure design and support
MFA + FIDO2 — multi-factor and passwordless authentication integration
Cloud Infrastructure — AWS, OCI, Azure deployment and management
Network Security — VPN, firewall, SIEM, threat monitoring
The site still exists — preserved exactly as it was at mfa2fa.com/wp/ as the migration baseline. The WordPress install, the theme, the content — all untouched.
The problems
Single point of failure — VPS goes down, site goes down, full stop
Manual deployments — WordPress updates, plugin updates, all by hand
No rollback — bad update? Restore from backup manually
No resource isolation — MySQL, Apache, PHP all sharing the same kernel
No HA — one machine, no redundancy
Config drift — changes made directly on the server, nothing in source control
The real problem wasn't WordPress. WordPress is fine — it runs 40% of the internet for a reason. The problem was the deployment model: manual, stateful, single-node, undocumented. That's what Kubernetes fixes.
What was preserved
The WordPress site was not deleted or replaced — it was moved into the cluster as a Deployment in the wordpress6 namespace, and the OVH nginx proxy routes /wp/ to it. The original content, theme, and database are all intact.
# wordpress6 namespace — what runs there now
kubectl get all -n wordpress6
NAME READY STATUS
pod/mysql-67bc7d8f75-v5gd4 1/1 Running
pod/wordpress-bfc789658-lt9gz 1/1 Running
pod/wordpress-bfc789658-pn27z 1/1 Running
NAME TYPE EXTERNAL-IP
service/mysql ClusterIP <none> # internal only
service/wordpress LoadBalancer 10.99.101.205 # MetalLB
✓ The WordPress pods use the same image (wordpress:php8.3-apache) and the same MySQL database. The only change is that they run in containers, behind a LoadBalancer, on a 3-node cluster — with rolling updates, resource limits, and restart policies.