Hosting WordPress Yourself 2017 Update

It’s been 2 years since I started writing the Hosting WordPress Yourself series, and in that time a lot has changed! If you had tried following along with the series recently you will probably have noticed that a few of the steps outlined in the articles no longer worked, or were no longer relevant. A few exciting new technologies and services have also been introduced over the last few years (e.g. PHP 7.1, Let’s Encrypt, HTTP/2) which can improve both the performance and security of your sites. As such, Brad suggested that I update the entire series to reflect what’s changed over the last couple of years.

The existing articles in this series have already been updated with the changes that follow. This article serves as a changelog and documents what’s changed in each article.

Part 1 – Setting Up a Virtual Server

The steps involved with setting up a secure virtual server have mostly remained the same. The only change in this article is that Ubuntu 16.04 is installed, which is the latest LTS release.

Part 2 – Installing Nginx, PHP and MariaDB

A lot has changed in part 2, and I’ll explain each section separately.

Nginx

Previously, I recommended that you install Nginx with the fastcgi_cache_purge third party module compiled-in. This would allow you to conditionally purge the FastCGI cache whenever your site content changed. However, I’ve since stopped using this module for a few reasons:

  • The module hasn’t been updated in over 2 years.
  • Updating Nginx to the latest version was often tedious as it involved compiling Nginx from source. The majority of Nginx repos don’t include the fastcgi_cache_purge module and those that do often ship older versions of Nginx.
  • It’s difficult to determine which cache keys should be purged when your content changes. If you publish a new post, various other pages need clearing from the cache, such as the blog index and archives. I found it more reliable to clear the entire cache when the site content changed.

I now recommend that you install the latest mainline version of Nginx directly from the community repos, which are updated often and contain the most useful modules pre-compiled.

PHP 7.1

PHP 7 landed just over 12 months ago and introduced a number of new features, the standout feature being the significant increase in performance. To test the performance gains for myself I decided to run some benchmarks using Blitz. The exact same server was used to perform these tests, the only difference being the fastcgi_pass directive in Nginx, which I switched between PHP 5.6 and PHP 7.1.

PHP 5.6 was able to handle 525 hits in 60 seconds:

PHP 7.1 managed 2,004 hits in 60 seconds:

That’s almost a 300% increase! If your site has pages that can’t be cached, upgrading to PHP 7+ is a no brainer and can significantly decrease your server load.

MariaDB

I switched from using MySQL to MariaDB a while back and have had no problems in doing so. It’s actually a fork of MySQL and is maintained by the original MySQL authors. I choose MariaDB because it offers more features and speed improvements over MySQL. It’s also a drop in replacement so works just like MySQL with the exact same APIs.

Part 3 – Setting Up Sites

Not a lot has changed in this article. The only difference is the inclusion of IPv6 directives in Nginx.

Part 4 – Server Monitoring and Caching

The section on Opcode caching has been removed because it’s enabled by default in PHP 7. The only other change was touched upon earlier with the removal of the fastcgi_cache_purge module. Due to this I now use the Nginx Cache plugin by Till Krüss, which purges the entire FastCGI cache whenever your content changes.

Part 5 – Cron, Email and Automatic Backups

At the beginning of last year Mandril announced that they were ending their free plan for outgoing email. I’ve since switched to Mailgun, which is a product by Rackspace. I’ve had no issues whatsoever and it’s free for your first 10,000 emails each month.

Part 6 – HTTPS and HTTP/2

The steps in this article have been greatly simplified due to the introduction of Let’s Encrypt. It’s no longer necessary to purchase an SSL certificate and instead I demonstrate how to use the new Certbot client to obtain and automatically renew certificates. I’ve also replaced the steps on enabling SPDY with enabling HTTP/2.

Part 7 – Nginx Security Tweaks, WooCommerce Caching, and Auto Server Updates

Everything in this article is still relevant. The only changes made were how to enable automatic server updates for Ubuntu 16.04.

Part 8 – Complete Nginx Configuration

Nothing in this article has changed. The GitHub repo has continued to be updated over the last couple of years and in my opinion it’s still the best base configuration for hosting WordPress on Nginx.

Although this article is relatively short it’s taken a fair amount of time to update the entire series. I really hope that you’ve found the updates useful and welcome any comments you may have.

About the Author

Ashley Rich

Ashley is a PHP and JavaScript developer with a fondness for solving complex problems with simple, elegant solutions. He also has a love affair with WordPress and learning new technologies.

  • This is a really fantastic writeup, Ashley. Delicious Brains talent staying tasty with the content…

  • Great stuff, ashley. Just wanted to drop a not that there’s an alternative to the Nginx Cache plugin that you might want to have a look at though it may not make any big differences for you. It’s called Nginx Helper https://de.wordpress.org/plugins/nginx-helper/

  • Cena

    Hi Ashley – thanks for the great writeup.

    Just wanted to note that if you’re using Jetpack, there’s currently a known incompatibility with PHP 7.1: https://github.com/Automattic/jetpack/issues/6106

  • Francisco García

    Thank you so much Ashely, you don’t have idea how much your guide has helped me. Thank you so much again!!.

  • Neil McGann

    Thanks for this terrific series. The parts about nginx and fast cgi caching are better than just about any other nginx tutorial I have found, WordPress-specific or otherwise.

    I didn’t know about pushbullet before either, so that has been a good find. I had to write my own php command line wrapper program though as the shared hosting that my personal blog runs on has a very old version of curl in the shell that won’t talk https properly.

  • i neutrality

    Hi Ashley Thanks for the great articles. However, I was wondering what is your view in swap file space. Would it help the server especially for an instance with lower memory?

    • It can certainly help protect against out of memory errors, but DigitalOcean doesn’t recommend you enable it on SSDs:

      Although swap is generally recommended for systems utilizing traditional spinning hard drives, using swap with SSDs can cause issues with hardware degradation over time. Due to this consideration, we do not recommend enabling swap on DigitalOcean or any other provider that utilizes SSD storage. Doing so can impact the reliability of the underlying hardware for you and your neighbors.

      If you need to improve the performance of your server, we recommend upgrading your Droplet. This will lead to better results in general and will decrease the likelihood of contributing to hardware issues that can affect your service.

  • Nick

    I really enjoyed this entire guide, and ended up writing a set of shell scripts to automate installs. They “stamp” WordPress sites onto $5/mo fresh droplets based on most of your steps. Here is my repo, as I hope they can be of some use to you or your readers! I followed this updated guide for most of the security and cache advice, but I did add a few of my own changes into the configs. If anyone finds any errors or has questions, please let me know.

    https://github.com/itcarsales/dropletTools

  • Hello,
    I have followed all of the step.
    But when i am trying to comment my website.
    The first time is success, but the second time is failed and show FTP / SFTP requirement.
    I don’t know what happen, but maybe about the permission about the nginx user.

    Any advice for that?

    Thank you,
    Frans Wiradinata

    • i have the same problem with some plugins!

    • i dont think that the problem is the permissions, because the user is “superuser”

    • i think the problem (in my case at least) is because the error web i use sudo mysql_install_db and gave me an error, but i can continue the tutorial even with that error

    • I found a solution, edit the file wp-config.php and add this define( ‘FS_METHOD’, ‘direct’ );, and restart nginx 🙂

      • Nick

        Checking in – I found that I had the same issues. I am updating my auto-installers and repos with this code, thanks!!

  • davidbitton

    @A5hleyRich:disqus why are you redirecting www to non-www? Is there any reason why I can’t turn this around and forward non-www to www? Thanks!

  • One little glitch with MariaDB on Docker on Windows is that it just does not work with volumes. So you may need to get back to MySQL which works in that configuration if you happen to hit that scenario.

  • Andy Lyon

    Hi Ashley, thanks for this set of articles, it’s really useful. Just wondering if you guys have any recommendations other than Blitz as it looks like they’ve shut up shop now.