Self-Hosting WordPress With Docker Compose On Enterprise Hardware

WordPress powers roughly 43% of all websites on the internet, making it the world’s most popular content management system with over 60% CMS market share. From small personal blogs to major mastheads like The Age and Sydney Morning Herald, through to NASA, Disney, The White House and parts of Microsoft’s web presence, WordPress is everywhere. There is a reason for this dominance: it’s flexible, it’s open source, it’s free, and it scales from a Raspberry Pi to enterprise infrastructure.

As of December 2025, WordPress.org (self hosted) and WordPress.com (managed) remain the go-to platforms for anyone wanting to get online quickly. You can host WordPress on WordPress.com, in the cloud on Azure or AWS, on various managed hosting providers, or you can do what I do and self-host it on your own hardware.

This post is not about why you should use WordPress, but rather how I arrived at my current self-hosting configuration and why I believe Docker Compose on enterprise hardware is the best path for those wanting control, performance, and simplicity.

My Journey Through WordPress Hosting

Over the years I have hosted WordPress in almost every configuration imaginable. I started like many others on shared web hosts, those $5/month deals where you’re crammed onto a server with hundreds of other sites. Performance was inconsistent, control was limited, and when things went wrong you were at the mercy of support tickets.

From there I moved to VPS providers, which gave me more control and dedicated resources. This was better, but I was still paying monthly for compute that sat idle most of the time. Then came the cloud era, and I experimented with Azure App Services, AWS Lightsail, and various container services.

The Cloud Reality Check

Now, let me be clear. You absolutely can host WordPress in AWS or Azure and do it well. I have architected cloud solutions professionally for years and understand the value proposition. Azure App Service for WordPress, AWS Lightsail, EC2 with RDS, Azure Container Apps, the options are endless and they work brilliantly for the right use case.

But here is the thing: for my modest needs, it is just cost I do not need and whilst I used to work for Amazon and Microsoft, the reality is today, the cloud isn’t free.

Let me break down the numbers. A basic Azure App Service plan capable of running WordPress with reasonable performance starts around $50-70 AUD per month. Add an Azure Database for MySQL and you are looking at another $30-50 per month minimum. Want decent storage? More cost. Want backups? More cost. Want staging slots? You guessed it.

AWS is similar. A t3.small instance suitable for WordPress runs around $15-20 USD per month. Add RDS for the database at another $15-25 per month. Elastic IP, EBS storage, data transfer, CloudWatch monitoring, it all adds up. Before you know it you are spending $60-100 USD per month on what is fundamentally a blog.

Over three years that is $2,160 to $3,600 USD. For that money I bought a DL380 G9 with more compute than I will ever need, SSDs that will outlast several cloud subscriptions, and I own the hardware outright. My ongoing costs are electricity (the DL380 draws around 200W under typical load) and my existing internet connection.

The cloud makes absolute sense when you need global distribution, auto-scaling, high availability across regions, or when you are building for enterprise clients with SLAs. I deploy cloud architectures professionally and will continue to do so. But for a personal blog, a small business site, or a hobbyist project where you control the traffic expectations, the cloud is solving problems you do not have while charging you for the privilege.

Self-hosting on enterprise hardware is not about being anti-cloud. It is about right-sizing the solution to the problem. My blog does not need to scale to a million users overnight. It does not need five-nines availability. What it needs is to load fast, stay online, and not cost me a subscription fee every month for the next decade.

I then went through a NAS phase, running WordPress on Synology and QNAP devices. This worked reasonably well for low-traffic sites, but the ARM processors and limited RAM in consumer NAS devices meant performance ceilings were real, especially when plugins and caching came into play.

And here I am today, running WordPress on a HP ProLiant DL380 G9 with Docker Compose, and I can confidently say this is the best configuration I have used for self-hosting.

Why Enterprise Hardware?

The DL380 G9 is enterprise-grade server hardware that has aged out of corporate data centres. You can pick these up for a few hundred dollars now, and what you get for that money is remarkable: dual Xeon processors, support for hundreds of gigabytes of RAM, redundant power supplies, hardware RAID controllers, and build quality designed for 24/7 operation in demanding environments.

My configuration is relatively modest but more than capable:

  • HP ProLiant DL380 G9
  • Dual Intel Xeon E5-2680 v4 (28 cores / 56 threads total)
  • 128GB DDR4 ECC RAM
  • 4x Samsung 870 EVO SSDs in RAID 10

This hardware was designed to run enterprise workloads for Fortune 500 companies. Running WordPress on it is, frankly, overkill in the best possible way. The site you are reading right now is hosted on this configuration, served from my house over a 500/50Mbps connection, and without Redis or any advanced caching this setup can comfortably handle tens of thousands of concurrent users.

Why Docker Compose?

After years of managing WordPress installations manually, dealing with PHP version conflicts, MySQL upgrades gone wrong, and permission issues that would make you want to throw your keyboard, I have found Docker to be the easiest path forward.

Docker Compose gives you:

  • Reproducible deployments (your compose file IS your documentation)
  • Easy updates (pull new image, recreate container)
  • Isolation (WordPress, MariaDB, and Nginx all in their own containers)
  • Portability (move to different hardware by copying compose file and volumes)
  • Rollback capability (tag your images, keep old volumes)

When I need to update WordPress or MariaDB, it is a simple docker compose pull followed by docker compose up -d. Compare this to the old days of SSHing into a server, backing up databases manually, updating PHP, praying nothing breaks, and debugging for hours when it inevitably does.

The Docker Compose Stack

Below is my current Docker Compose configuration. It is intentionally simple and does not include Redis or advanced caching because, honestly, with this hardware it is not needed for my traffic levels.

networks:
  wp-net:
    driver: bridge

services:
  mariadb:
    image: mariadb:11.8
    container_name: mariadb_wp
    environment:
      MARIADB_ROOT_PASSWORD: your_root_password
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wpuser
      MARIADB_PASSWORD: your_wp_password
    volumes:
      - /mnt/ssd_pool/appdata/wordpress/db:/var/lib/mysql
    restart: unless-stopped
    networks:
      - wp-net

  wordpress:
    image: bitnami/wordpress:latest
    container_name: wordpress
    depends_on:
      - mariadb
    environment:
      WORDPRESS_DATABASE_HOST: mariadb
      WORDPRESS_DATABASE_NAME: wordpress
      WORDPRESS_DATABASE_USER: wpuser
      WORDPRESS_DATABASE_PASSWORD: your_wp_password
    volumes:
      - /mnt/ssd_pool/appdata/wordpress/wp:/bitnami/wordpress
    restart: unless-stopped
    networks:
      - wp-net

  nginx-proxy-manager:
    image: jc21/nginx-proxy-manager:latest
    container_name: nginx_proxy_manager
    restart: unless-stopped
    ports:
      - "81:81"
      - "8081:80"
      - "8443:443"
    volumes:
      - /mnt/ssd_pool/appdata/nginx-proxy-manager/data:/data
      - /mnt/ssd_pool/appdata/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
    networks:
      - wp-net

Let me break down the key components.

MariaDB 11.8
I use MariaDB over MySQL for WordPress. It is a drop-in replacement with better performance and remains truly open source. The data is persisted to an SSD pool mounted at /mnt/ssd_pool/appdata/wordpress/db.

Bitnami WordPress
The Bitnami WordPress image is well-maintained and includes Apache, PHP, and WordPress pre-configured. It handles permissions correctly out of the box, which is something that trips up many Docker WordPress deployments.

Nginx Proxy Manager
This provides a web-based interface for managing reverse proxies and SSL certificates via Let’s Encrypt. Port 81 is the admin interface, while 80 and 443 handle HTTP and HTTPS traffic respectively.

Performance Expectations

With this configuration and without Redis or object caching, you can expect:

  • Time to First Byte (TTFB): < 200ms
  • Full page load: < 1 second for typical blog pages
  • Concurrent users: comfortably 10,000+ with Nginx caching enabled

The DL380 G9 with SSDs removes the traditional bottlenecks of WordPress hosting. The dual Xeons provide more than enough CPU headroom for PHP processing, the 128GB RAM means MariaDB can cache your entire database in memory, and the SSD RAID provides the IOPS needed for WordPress’s write-heavy nature.

For context, most managed WordPress hosts advertise being able to handle a few hundred concurrent users. Enterprise hosts charge premium prices for what this second-hand server delivers.

Self-Hosting From Home

Yes, I host this from my house on a 500/50Mbps connection. The 50Mbps upload is the limiting factor, but for a blog this is more than adequate. At 50Mbps you can theoretically serve:

  • ~6MB/s of sustained traffic
  • With average page sizes of 500KB, that is 12 full page loads per second
  • Or 720 page loads per minute, 43,200 per hour

In reality, with browser caching and CDN (I use Cloudflare), the actual bandwidth requirements are much lower. Cloudflare handles the heavy lifting for static assets, and my server only needs to generate dynamic content.

The main considerations for home hosting are:

  • Static IP or dynamic DNS (I use Cloudflare tunnels)
  • ISP terms of service (check yours does not prohibit hosting)
  • Power reliability (the DL380 has dual PSUs, and I have a UPS)
  • Cooling (enterprise servers are loud, keep them in a garage or dedicated room)

Summary

My WordPress hosting journey has taken me from shared hosts to VPS to cloud to NAS and finally to enterprise hardware running Docker Compose. For those wanting maximum control, best performance per dollar, and the simplest update path, I believe this is the optimal configuration.

The DL380 G9 can be had for a few hundred dollars. Add a few SSDs, install Proxmox or Ubuntu Server, deploy this Docker Compose stack, and you have a WordPress host that rivals enterprise managed platforms.

Is it for everyone? No. If you want zero maintenance, go with WordPress.com or a managed host. But if you are the type of person who enjoys tinkering, wants to learn, and values owning your infrastructure, self-hosting WordPress with Docker Compose on enterprise hardware is immensely satisfying.

Reach out if you have questions, and if you have extended this setup in interesting ways leave a comment.

Thanks
Shane Baldacchino

Leave a Comment