Recently, a friend of mine dealt with a server administrator’s worst nightmare. They were hosting multiple subdomains for different clients on a single server, and one of the sites got hacked. Because the server was configured to run all the websites under a single user account, the hacker didn’t just compromise one site—they were able to traverse the server directories and inject malicious code into every single website on the machine.
To make matters worse, they were dealing with two major infrastructure challenges:
- The Single IP Trap: They only had one public IP address, meaning they couldn’t just throw each site onto its own dedicated server without a massive headache.
- No Disk Quotas: There were no hard disk quotas enforced. A single site with a runaway log file or a malicious upload could fill up the entire server’s storage, crashing the other sites right along with it.
They needed a way to securely host multiple sites on one machine with strict boundaries. So, I built a custom solution for them.
The Solution: A Zero-Trust PaaS Architecture
I engineered a custom WordPress Platform-as-a-Service (PaaS) that runs entirely on a single server but treats every single website like it is locked in a vault.
Instead of throwing everything into one big /var/www folder under one user, the new setup completely isolates every tenant.
Here is how it transformed their hosting environment:
- Total Container Isolation: Every site now runs in its own dedicated Docker containers (WordPress, MariaDB, Redis). If one site gets breached, the hacker is trapped inside that specific container and cannot see or touch any other sites on the server.
- Strict Disk Quotas: To solve the storage issue, the deployment script creates native Linux virtual disks (
.imgfiles) for each site. A site is given exactly 5GB (or whatever is allocated). If it hits the limit, only that site stops—the rest of the server is completely unaffected. - Single IP Routing with Traefik: Even with just one public IP, the Traefik reverse proxy acts as an intelligent traffic cop, routing incoming requests to the correct isolated container behind the scenes.
- Zero-Trust Security: The server has no inbound ports open at all (not even 80 or 443). Everything is securely tunneled through Cloudflare, blocking direct IP attacks entirely.
It took a disastrous hack to force an upgrade, but their infrastructure is now enterprise-grade, highly scalable, and completely bulletproof.
⚠️ Crucial Prerequisites Before You Start
Because this platform uses a Zero-Trust architecture, it relies heavily on Cloudflare to act as your perimeter firewall and DNS provider. Before cloning the repository, you must have:
- A Cloudflare Account: Your root domain (e.g.,
yourdomain.com) must be actively hosted on Cloudflare using their nameservers. - A Zero Trust Tunnel Token: You need to create a tunnel in your Cloudflare Zero Trust dashboard and obtain the Tunnel Token. This is what allows your server to securely phone home to Cloudflare without opening any firewall ports.
- A Linux Server: A Debian or Ubuntu server with Docker and Docker Compose installed.
How to Deploy Your Own WordPress PaaS
I have open-sourced this entire architecture. It is completely path-independent, meaning you can drop it onto any server and have your own hosting company online in minutes.
1. Install Required Utilities
Before we begin, we need to install git to clone our repository and the htpasswd utility, which we will use to generate secure dashboard passwords.
Depending on your operating system, use the appropriate package manager below. (Note: The package containing htpasswd is called apache2-utils on Debian/Ubuntu, and httpd-tools on RHEL/CentOS).
For Debian / Ubuntu systems (apt):
sudo apt update
sudo apt install -y git apache2-utils
For RHEL / CentOS / AlmaLinux systems (yum):
sudo yum check-update
sudo yum install -y git httpd-tools
2. Optimize Network for Cloudflare Tunnels (QUIC)
Cloudflare Tunnels prefer using the QUIC protocol (UDP) for faster, more reliable connections. To prevent the operating system from dropping packets due to small buffer sizes, we need to increase the UDP buffer limits.
Create a new sysctl configuration file:
sudo nano /etc/sysctl.d/99-cloudflared-quic.conf
Add the following parameters:
net.core.rmem_max=8388608
net.core.wmem_max=8388608
Apply the changes immediately:
sudo sysctl --system
3. Install Docker Engine
For a production environment, it is highly recommended to use the latest official Docker releases rather than the default packages that come with your Linux distribution. Head over to the Official Docker Installation Guide, select your operating system, and follow the exact steps provided there to install Docker Engine and Docker Compose.
4. Create Isolated Docker Networks
To maintain a secure architecture, we will separate our traffic. The frontend network will handle communication between Cloudflare and WordPress, while the backend network will completely isolate the WordPress containers from their respective databases.
Run the following commands to create the networks:
docker network create frontend
docker network create backend
5. Generate Your Dashboard Password
Now that the htpasswd utility is installed, you can generate the hashed password required for your .env file to protect the Traefik/Cloudflare dashboard.
Run this command, type your desired password, and it will output the properly escaped string for your Docker Compose configuration:
echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'
6. Cloning the Code
Here is how to set it up:
Step 1: Clone the Infrastructure Clone the repository. Because of how we engineered the Docker variables, you can place this anywhere on your machine.
git clone https://github.com/induslevel/wp-paas.git /opt/wp-paas
cd /opt/wp-paas
Step 2: Configure Your Perimeter Navigate to the infrastructure folders and configure your environment variables. This is where you will paste your Cloudflare Tunnel token.
# Set up your Cloudflare Tunnel
cp infrastructure/cloudflared/.env.example infrastructure/cloudflared/.env
nano infrastructure/cloudflared/.env
# Set up your Traefik Router
cp infrastructure/traefik/.env.example infrastructure/traefik/.env
nano infrastructure/traefik/.env
# Set up your Olivetin Container
cp infrastructure/olivetin/.env.example infrastructure/olivetin/.env
nano infrastructure/olivetin/.env
Step 3: Boot the Core Spin up the Traefik router, Cloudflare tunnel, and the management UI.
cd infrastructure/traefik && docker compose up -d
cd ../cloudflared && docker compose up -d
cd ../olivetin && docker compose up -d
Effortless Management with OliveTin
I didn’t just want to build a secure backend; I wanted it to be incredibly easy for my team to manage without handing out SSH access to the server. To solve this, the architecture includes a pre-configured OliveTin dashboard. OliveTin is a lightweight web interface that safely maps underlying Linux shell scripts to a beautiful push-button UI.
From your browser, you can seamlessly scaffold and boot sites. Enter a domain name (e.g., client.com), click start, and watch as the backend automatically allocates the virtual disk, generates secure database passwords, and spins up the isolated WordPress environment.
What’s Next: Bulletproof Disaster Recovery
A hosting platform is only as good as its disaster recovery plan. To make this architecture truly indestructible, the next step on the roadmap is integrating Duplicati for automated, off-site backups. By utilizing block-level deduplication, Duplicati will monitor the master PaaS directory and securely ship encrypted snapshots to cloud storage (like Backblaze B2 or Cloudflare R2). This master-vault strategy ensures that we can instantly recover a single accidentally deleted file for a client, or restore the entire server architecture onto a brand-new machine in minutes in the event of a total hardware failure.
Get the Code
It took a disastrous hack for my friend to upgrade, but their infrastructure is now enterprise-grade, highly scalable, and completely bulletproof. You can grab the full code, dynamic bash scripts, and Docker configuration files over on the IndusLevel GitHub repository. 👉 [Link to the GitHub Repository: View WP-PaaS on GitHub]