Introducing Our FrankenWP Maintained Docker Image

It’s official. We are creating and maintaining a WordPress Docker image built on FrankenPHP, Caddy, & custom server caching modules.

I am excited about the opportunities that are now available with this release.

Get Started

Why Do It?

You may ask why another WordPress Docker image needed to be created. The standard Docker image is well battle-tested in production workloads.

But, it can be better.

1 Image as Fast as PHP-FPM + fastcgi

This single FrankenWP Docker image includes built-in distributed server caching through Souin & Caddy server that is just as fast as PHP-FPM + fastcgi. The benefits are that you only need 1 Docker Image, and the server cache can be mounted on as many autoscaled servers as you want.

Here’s a visual Comparing WordPress with Nginx + PHP-FPM Docker Compose to WPEverywhere FrankenWP.

Nginx + PHP-FPM Docker Compose File

FrankenWP Docker Compose

Notice the difference?

You don’t need 2 be running multiple containers, and you don’t have to create and mount custom configuration files.

1 image, and override configurations only when desired.

Performance at Scale

The goal of FrankenWP wasn’t to have the fastest WordPress server. I’m sure other configurations are faster. But, it did need to compete and perform at scale.

And it does.

I ran the FrankenWP Docker image in a Loader.io test with 10,000 requests in 1 minute and compared it with the standard Apache WordPress image.

The results show that the FrankenWP image can handle the load without issue, whereas the Apache image starts to error.

FrankenWP Image Loader.io with 10k Requests

Apache WP Image Loader.io 1,800 Requests (errors out on more)

Real-World Production Server Response Example

Here is an example of a production website running on the FrankenWP Docker image. They also use a prominent site builder plugin that is known to slow down sites.

What about PHP-FPM + Nginx comparison?

Indeed, the Apache image isn’t known to be the fastest option for deploying WordPress at scale. I wanted to compare one image to another, and this made the simplest test.

I may compare FrankenWP with Nginx + PHP-FPM or Litespeed, but this accomplished my goal of confirming that this image can run WordPress in production at a large scale.

Decreasing Costs in the Cloud

The challenges of scaling WordPress are all the optimizations required. You need opcache, cache plugins, Redis, fastcgi with PHP-FPM, and servers to handle the memory.

But what if you could deploy a single WordPress container into a $6 / month 1gb ram + 2 cpu server that can handle production workloads without extra configurations?

It’s possible.

The production instance above & load tests are running on a single t4g.micro ec2 in AWS. On-demand, it costs only $6 / month.

CPU Utilization averages less than 10% with peaks to 20%

Memory averages 30% utilization and peaks at 50% during higher traffic periods.

This single instance can reliably manage more than 100k+ monthly production visitors with first-rate user experiences.

What’s Going on Inside the Docker Image

There are a few core pieces that make up this WordPress Docker image:

  • FrankenPHP
  • Caddy Web Server
  • Sidekick Server Caching Service
  • Opcache
  • Base WordPress Docker image

FrankenPHP

FrankenPHP calls itself the modern PHP application server written in Go. I agree with this claim. It compiles with a custom fast PHP c runtime in a Caddy Web Server. We do a unique build to pull in the Souin cache module, but FrankenPHP is what keeps us from needing PHP-FPM.

Caddy Web Server

Caddy is to Nginx, which is what FrankenPHP is to PHP-FPM. Caddy is the underlying web server that powers it all. It is written in go and takes advantage of the standout concurrency feature: Goroutines.

Caddy allows us to run concurrent PHP requests and other processes that can run in the background. We can send a response to the browser and execute a data processing job in the background.

Sidekick Caching

The Sidekick cache is a custom server caching solution we developed as a Caddy module. It stores content on-disk and in-memory to be distributed within sub-100 millisecond responses even in heavy load times.

The default cache is set to 8000 seconds but can be overwritten with a TTL environment variable.

The cache also includes a built-in REST API whenever you need to flush the entire cache or single pages. The API routes can be customized via environment variables, and I keep access to them only through the application.

WordPress Docker Image

We copy the WordPress content from the standard WordPress Docker image. This allows us to use the custom functions added to access the Docker environment variables in wp-config.php. It is also good practice as it helps us stay updated with the latest WordPress versions.

Ready to Get Started?

Checkout the github repo & Docker Hub images to start testing today.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *