High-Availability WordPress Cluster with Docker Swarm & EFS

Written by JP La Torre

Summary:

In this article, we’ll cover step-by-step how to setup and deploy a High-availability WordPress cluster based on Docker Swarm and Amazon’s Elastic Filesystem (EFS).

By following these simple steps, you’ll have a clean install of WordPress running on Docker Swarm:

  • Create EFS volume
  • Mount EFS globally
  • Create RDS database
  • Deploy WordPress
  • Scaling WordPress

WordPress is by far the most popular CMS on the planet, with roughly 60% market share as of the time of this writing.

As WordPress users ourselves, and after sifting through many incomplete or outdated guides on the subject, we decided to share a DIY-approach to replicate some of the technology we are using at Caylent to automate the deployment of HA WordPress using Docker Swarm.

With more businesses realizing the negative impact that downtime and poor performance can bring many are making the shift from running single servers to highly-available clusters, monoliths to microservices, and legacy apps to containers.

One of the persistent problems has been that WordPress does not scale very well, yet many high-traffic websites rely on it. We’re going to solve this by using a pretty simple stack consisting of Docker Swarm, Amazon’s EC2, EFS, Relational Database Service (RDS), and an Elastic Load Balancer (ELB).

Let’s get started!

Prerequisites

For the sake of this guide, you’ll need to have a few things already in place:

I used Ubuntu 14.04 LTS running kernel 3.13.0-91-generic, though the process will work pretty much the same on most Debian-based operating systems.

I highly recommend you read and follow our previous guides on building the stack and installing Docker Swarm as this article assumes you already have those essentials.

Create EFS Volume in AWS Console

Log in to your AWS Console and navigate to EFS > Create file system.

Next, select the VPC and assign mount targets according to the Availability Zones where your instances are located.


Step 2 of the EFS wizard is optional and lets you assign tags to your filesystem.

Review the settings in Step 3 and click Create File System.

Adjust Firewall Rules on EFS Security Group

If you followed our previous articles you should have one security group each for Swarm masters and Swarm workers.

We need to add both these Swarm security groups to the EFS security group to allow inbound traffic over the NFS protocol.

Navigate to EC2 > Network & Security > Security Groups. Locate the security group that EFS used in the last step. Under the Inbound tab click Edit.

Add one NFS (port 2049) inbound rule for each Docker Swarm security group. When you’re done it should look like the image below.

 

These should be the only two entries. We suggest you don’t allow All traffic for security reasons.

Click Save.

Install NFS and create mounts

Open up a terminal client, SSH into each EC2 instance on your cluster, and run the following commands on every machine.

First, let’s install the NFS drivers.

sudo apt-get install nfs-common

 

On each machine, create our filesystem directory.

sudo mkdir /mnt/efs

 

Mount the EFS filesystem using the DNS address (replace <> brackets).

sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 <your-EFS-DNS-Name>:/ /mnt/efs

 

On each instance make sure the DNS for your mount target is in the same Availability Zone to ensure the lowest possible latency.

We can verify the mount in several different ways. We can check this with a plain mount or findmnt command, but df -h will give a more human readable output, like this:

Create a WordPress directory inside the EFS mount

Type sudo mkdir –p /mnt/efs/wordpress into your terminal. You only need to do this on one machine since all instances now have the EFS volume mounted.

We can easily verify that other instances in our cluster have access to this directory by typing ls /mnt/efs on each host.

Mounting the volume at boot

We can mount the EFS volume automatically at boot by adding a line in the /etc/fstab file on each of the instances. This is optional but highly recommended.

If you do not do this the mount will disappear upon system reboot and you will have to manually mount the volume again.

sudo nano /etc/fstab

 

Add the following line to the end of your fstab file:

<your-EFS-DNS-name>:/ /mnt/efs nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0

You can easily confirm this works by performing a reboot and then verifying that the volume is mounted.

Setup RDS database

WordPress requires a relational database. MySQL is by far the most popular option, though others like MariaDB and PostgreSQL work fine (though you may need additional plugins). I’ll be using MySQL.

In the AWS Console, navigate to RDS > Launch a DB instance.

Select MySQL > Community Edition. On the next screen, you will be prompted to choose an environment depending on your intended usage. Select Production.

Check out the screenshot below to see how I setup my RDS database.

Remember, we want a Multi-AZ RDS database. This introduces fault tolerance at the database level. Keep in mind that if you elect not to use Multi-AZ your database costs will be cut in half but the stack will have a single point of failure.

AWS recommends at least 100 GB of storage if you use general purpose SSD.

I am using a db.t2.medium instance size but your particular needs may vary. One of the benefits of using RDS is that you can change instance size later with relatively minimal disruption.

Click Next Step.

Now you’re on Step 4, the final step in creating your RDS database. Select the VPC you used to create the EFS volume and EC2 instances.

You can create a new security group specifically for RDS or use the default VPC security group. The EC2 instances will need inbound access on port 3306. I elected to use a new security group to separate things out a bit more.

Give the database a unique name, like WordPress.

Click Launch.

 

Deploy WordPress

In your terminal, run the following commands on one of your Swarm Master nodes.
(Note: Replace bracketed <> items).

docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
--gateway 10.0.9.254 \
caylent-network

 

docker service create --name wordpress \
--publish 80:80 \
--mount type=bind,source=/mnt/efs/wordpress,target=/var/www/html \
-e WORDPRESS_DB_HOST=<your-RDS-DNS-endpoint>:3306 \
-e WORDPRESS_DB_USER=dbMaster \
-e WORDPRESS_DB_PASSWORD=<your-RDS-password> \
-e WORDPRESS_DB_NAME=wordpress \
-e WORDPRESS_TABLE_PREFIX=wp_ \
--replicas 1 \
--network caylent-network \
wordpress:4.8.0-php7.1-apache

Don’t worry that we’re only running one container for the moment. We’ll scale this service right after we finish our WordPress setup.

Modify Directory Permissions

You may need to change the file and folder permissions on the WordPress directory to allow proper read/write/execute access.

cd /mnt/efs/wordpress
sudo chown www-data:www-data -R *
sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;

 

Finalize WordPress Installation

At this point, you should have a clean install of WordPress running.

You’ll want to locate the machine that is running the singular Wordpress container.

Run docker service ps wordpress in your terminal to see which host the container is running on.

Note that if your container isn’t running on the machine you’re currently using, as was my case, you’ll have to find the corresponding public IPv4 address from the AWS console.

Fire up your browser and point it to that public IP.

You’ll be greeted with the familiar WordPress setup page.


Congratulations! You now have a fully fledged high-availability WordPress install, backed by Docker Swarm and EFS.

Scaling WordPress

Now that we’ve got WordPress setup properly, you’ll want to scale the service.

$ docker service scale wordpress=10

wordpress scaled to 10

High-availability WordPress cluster conclusion

In this article, I demonstrated how to create a high-availability WordPress cluster using Docker Swarm and EFS.

This covers a typical N+1 redundant setup that can handle single failures at every level – network, compute, storage, or database.

If you’re interested in automating this entire process, then I’d like to invite you to check out Caylent, a SaaS platform that makes it easy to deploy apps, like WordPress, inside your own AWS account. Caylent automates the entire process covered here and a lot more. Best of all, it is free to get started.

As always, we’d love your feedback and suggestions for future articles.

The DevOps container management platform

  • Amazon AWS
  • Microsoft Azure
  • Google Cloud
  • Digital Ocean

Unlimited users. Unlimited applications. Unlimited stacks. Easily manage Docker containers across any cloud.

Get Started—Free!
Top
%d bloggers like this: