WordPress is the worlds most popular CMS with over half of all websites using it. It is easy to use and there are tons of themes and plugins to set up your site just the way you want.
So what is there not to like about it? Well, quite a few things actually. The first issue is security. WordPress has a long history with security flaws in the core system and in different plugins. More than one site has been compromised over the years.
Another issue is scalability and performance. To get good performance from a heavily used WordPress site is something that requires expertise and resources. We are talking clustering, database replication and caching.
But what if I told you that there is a way to host a WordPress site that is secure, fast, cost-effective and can be setup by simply following the instructions in this blog post? Lets have a look!
What I am aiming at is to set up 2 separate environments. The first one is the development environment. Here I will be using WordPress as a CMS to create my website. The other environment is the production environment where the content will be served to the users.
The development environment can be set up wherever you prefer. It could be running on your laptop. On your companies onsite servers. Or as in my example, on an AWS EC2 instance.
Using an EC2 instance is very convenient. It won't have to be a very powerful instance as only the editors will ever be accessing it. I can even shut it down when I am not editing. All this helps to keep the costs at a bare minimum. And access can be restricted using Security Groups.
Once I am done editing my site I use the plugin Simply Static. What this plugin does is export the WordPress site into a static HTML site. This static site is what I will be presenting to the users in the production environment.
Once I have my static HTML site downloaded I can upload this to AWS S3. S3 is a highly scalable online storage service. This allows me to have a place that will serve my static site. And I don't have to worry about maintaining any host server.
I could leave it at only using S3. But it can be made faster and more secure. Serving the website with a CDN allows users to connect to servers geographically close to them. This reduces latency and improves the experience. I also want to secure the site using SSL encryption. This secures that the content showed is truly coming from my site. And as a bonus it also helps in Google rankings. AWS has a CDN service called CloudFront that integrates nicely with S3 and allows for SSL encryption.
Setup WordPress on AWS EC2
Setting up WordPress on EC2 is as simple as spinning up an instance with an AMI that has WordPress preinstalled. I choose an image from Bitnami named bitnami-wordpress-4.8.php56-0-linux-ubuntu-14.04-x86_64-hvm-ebs.
Instance size doesn't matter as there will hardly be any load on it. The development server will not be accessed by the public. Therefore I can limit the security group so only my IP can access HTTP.
Once installed I can browse to the public IP of the instance and log in to WordPress using the default Bitnami username and password user/bitnami.
Simply Static plugin
Once in WordPress there are some plugins that have to be installed. The first one is Simply Static. This is the tool used to export the entire WordPress site into a static HTML site.
It is a very straight forward process to install this plugin. But one thing to consider is to configure the final domain name of the site. By default Simply Static will try to replace all links with relative URLs. This is a very flexible solution where you don't have to think about what domain you will use. But there are instances where it will be needed to have an absolute URL. That is why I changed the setting to use the static URL https://s3wordpress.deductivelabs.com. After that is setup it is possible to generate and download an static version of the site.
Comments and other dynamic content
The big downside with having a static site in place of a dynamic site is of course that you cant have any dynamic content. There is no server to process comments, forms or web shops. I am not planning to have a web shop on the site. But I would like to have a comment section. So how can I have a comment section without a server to process the comments. The answer is that I need to find someone else that is willing to process them for me. Luckily there are quite a few options to choose from. Such as Disqus, Facebook Comments and Staticman. For my site I picked Facebook Comments.
Upload to AWS S3
The static site is generated and exported. The site can be downloaded as an zip file. This makes it easy to download extract and upload to AWS S3. On S3 I have created a bucket with the same name as the site s3wordpress.deductivelabs.com. It doesn't have to have that name, but it makes it easy to keep track of the buckets that way. Something to keep in mind when uploading the files to S3 is to make sure that there are public read permissions. I also configure the bucket to be used as Static website hosting and enter the index.html as the index document.
AWS CloudFront as CDN
The site is now online and I could just point the hostname to the S3 endpoint. But to improve the latency for the end users and implement SSL I will also connect CloudFront.
CloudFront is the CDN of AWS. And what it does is to copy the data to over 90 Edge Locations around the world. By using different DNS replies the end user will be directed to the closest location with the fastest possible latency.
When I created my CloudFront distribution I did notice one peculiarity. When I direct and request for a directory on S3, such as https://s3wordpress.deductivelabs.com/hello-world, S3 automatically redirects this to the index.html object in the directory. This does not happen on CloudFront. And since this is exactly how my WordPress site is exported this is a problem. To solve this I was forced not to use S3 directly as the Origin, but instead to use the S3 Static website hosting endpoint. This allows S3 to redirect any requests for a directory to the index.html file. Which CloudFront then will cache.
As I want to use SSL, I will also select the Redirect HTTP to HTTPS option. And of course select the certificate for s3wordpress.deductivelabs.com that I have created in the Certificate Manager.
Once the CloudFront distribution is deployed I get the domain name d15tu1sbn9km0.cloudfront.net. I can now point my domain s3wordpress.deductivelabs.com as a CNAME.
The site is now online. It is fast, scalable and low cost. And the WordPress instance is securely tucked away on EC2. Far away from the end users.