How to Install WordPress on Ubuntu 20.04 and Speed Up Your Sites
This step-by-step guide contains everything you need to know about setting up a Ubuntu 20.04 server to run WordPress at lightning speed.
Congratulations, you’ve taken your first steps on your journey to hosting your own WordPress server! 🎉
This is a big deal.
Before we open a terminal and start running commands it’s important to explain who we are, why you should trust us, and why we’ve made certain decisions we’ve made in writing this guide.
The Authors: Experienced Sys Admins & WordPress Developers
Ashley Rich is the lead author of this guide. Ashley served with the Royal Air Force in the United Kingdom as an ICT Technician building and maintaining servers and networks for over five years. He joined Delicious Brains Inc in 2015 as a senior PHP developer working on popular WordPress plugins WP Migrate DB Pro and WP Offload Media. Less than a month after joining he published the first chapter in this guide which he has been iterating and updating ever since.
In 2018 he became lead developer on SpinupWP, a cloud-based control panel for hosting WordPress.
Brad Touesnard is the co-author of this guide. Brad is the founder and CEO of Delicious Brains Inc. As a developer, Brad has contributed to WordPress core in addition to publishing WordPress plugins praised by thousands of WordPress developers around the world.
In 2002, Brad co-founded a web hosting company, writing the entire control panel and billing system from scratch in PHP and MySQL. He continued to improve and maintain it for 10 years, until 2011 when the company was sold.
When it comes to setting up and maintaining a server to run WordPress, we’re all about practicality. If we can accomplish the same thing with less software, we’re going to go that route.
Of course it’s rarely that simple. There are often tradeoffs to balance against improvements. You’ll see when we discuss Varnish below.
Caching is King
Our customers are often surprised how much faster their site is after moving it onto their SpinupWP server. There can be lots of reasons why it’s faster, but the most likely reason is caching. With page caching enabled, you essentially turn your WordPress site into a static site.
And if you haven’t been living under a rock, you’ve probably heard the hype about static sites and how fast they are. Static site generators, JAM stacks, Gatsby, etc., are all the rage these days. It’s all very trendy.
Thing is, if you put a page cache in front of WordPress, it performs the same as a static site but has the huge benefit of having WordPress and its plugins available on the backend to enable dynamic features as you need them.
In this guide we’ll configure Nginx to cache whole pages and to serve from the page cache when appropriate. For requests that skip the page cache, we’ll configure Redis to cache database data in-memory and serve cached data from there instead of querying MySQL every time. The fewer queries you need to run against MySQL for a request, the faster the response.
This guide involves setting up a single server to host one or more WordPress sites. A single server is a single point of failure. That’s true. And years ago, before hot-swappable hardware and virtualization, this was a problem. But today Virtual Private Server (VPS) providers are incredibly good at keeping a single server operational.
In the past decade of running servers on AWS, Linode, and DigitalOcean, we don’t recall experiencing any down time as a result of hardware failure or some other problem with the server itself. It seems to always be a network issue that causes downtime.
There are lots of platforms out there touting the redundancy of their “grid” but they are equally vulnerable to downtime caused by a network issue. Not to mention that clusters are far more complex and have a lot more moving parts than a single server. This complexity is at least as likely to be the cause of downtime as it is preventing it. We’ll take a simple, boring VPS over some hyped-up grid any day of the week.
In the end, you just have to accept that even the biggest tech companies experience downtime and you will too.
There are a ton of different Linux distributions. For servers, the most popular are Ubuntu, Debian, and CentOS. Ubuntu is one of the most popular Linux distributions for a few reasons:
- Heavily focussed on usability
- A large selection of packages
- Frequent software updates
- A large community leading to more helpful resources
Frequent software updates can also be a drawback as it’s possible to introduce new bugs and conflicts as packages are updated. But Ubuntu has a Long Term Support (LTS) release that uses packages that are more stable. LTS releases occur every 2 years and are supported for 5 years – making them suitable for production servers.
Why Not Apache?
If you search “Nginx vs. Apache” you’ll find benchmark after benchmark of Nginx destroying Apache for serving static files. Nginx is a beast for serving static files. That’s its greatest strength.
Some providers install both Nginx and Apache2 with mod_php. When a request comes in, it is always first handled by Nginx. If the request is for a static file, Nginx serves it. No Apache needed. If the request is for a PHP page, Nginx forwards the request on to Apache, Apache’s mod_php processes it and returns a response to Nginx, and finally Nginx serves it.
Apache is really used as a PHP processor in this stack. But PHP comes included with a FastCGI process manager called PHP-FPM which can be used directly with Nginx. The flow with PHP-FPM is much the same, but we find it simpler to configure PHP-FPM than Apache + mod_php. PHP-FPM also feels lighter weight to us and seems to use fewer resources. It’s also nice that PHP-FPM comes included with the PHP package and there’s no need to install another software package and keep it updated.
Why Not Varnish Cache?
The simple answer is that FastCGI Cache is easier to configure, uses less resources, and performs better than Varnish Cache. Our benchmarks show that FastCGI Cache performs significantly better than Varnish Cache.
Although Varnish Cache is far more flexible, it is also far more complex. FastCGI Cache has been flexible enough for my needs over the years, so I don’t see the need for added complexity.
Like PHP-FPM, FastCGI Cache is easier to maintain because it comes included with Nginx. Having one less piece of software to maintain is always a big plus.
In fact, using Apache and Varnish would be two additional complex pieces of software to configure and maintain. This is how our stack compares to a platform that uses both Apache and Varnish:
Why Not Memcached?
Redis is a newer, more modern in-memory data store than Memcached. It has more features and seems to be a more popular choice in the WordPress community.
Why MariaDB instead of MySQL?
When I first chose MariaDB for this guide, it was because it offered more features and speed improvements over a MySQL database. It’s also fully open source (unlike MySQL) and has been adopted by a number of large companies.
While the latter continues to be true, it seems MySQL 8 has caught up in features and performance. This is why we offer both MySQL 8 and MariaDB options when setting up a new server in SpinupWP.
For this guide however, I’ve chosen to stick with MariaDB for now because by default MySQL 8 is configured for large scale enterprise applications. It requires a lot of configuration to make it suitable for our use. SpinupWP handles modifying configuration files automatically when setting up a new server.
With all those questions answered, let’s dive into setting up an Ubuntu 20.04 server and configuring it to run WordPress lightning fast.
Table of Contents
Set Up a Secure Virtual Server on DigitalOcean
In this chapter we’ll provision a new VPS at DigitalOcean with Ubuntu 20.04 LTS. We’ll login to the server via SSH, configure the hostname and timezone, install software updates, and set up automatic security updates. Then we’ll create a new sudo user, set up SSH login with keys instead of a password, and disable SSH for the root user. We’ll also install a firewall and fail2ban to protect against intrusion attempts.Read Chapter 1
Install Nginx, PHP 8.0, WP-CLI, and MariaDB
This chapter is all about setting up the software needed to run a WordPress site. First we’ll install Nginx and configure it with better settings for our use. Next we’ll install PHP and its packages required by WordPress and configure PHP-FPM. Then we’ll install WP-CLI and MariaDB.Read Chapter 2
Configuring Nginx to Serve Your First Site Over HTTPS
In this chapter we’ll discuss HTTPS and why it’s so important before updating our DNS and obtaining our first SSL certificate from Let’s Encrypt. Then we’ll add a new config file to Nginx for our first site complete with a redirect from HTTP to HTTPS. Next we’ll create a database for the site and we’ll use WP-CLI to install WordPress. We’ll wrap up with a discussion about creating more sites on the server.Read Chapter 3
Object Caching, Page Caching, and Other Speed Optimizations
We’ll start this chapter with a benchmark of site speed without caching and end it with a benchmark with caching enabled. We’ll install Redis and a companion WordPress plugin that will work together to enable object caching. Next we’ll return to our Nginx config files and add a batch of directives to enable FastCGI Cache and tell it what not to cache, including some directives for WooCommerce.Read Chapter 4
WordPress Cron and Email Sending
In this chapter, we’ll cover what cron is and how to get around some typical hurdles. Then we’ll set up automatic renewals of HTTPS certificates. Next we discuss why we don’t set up an email server and step through configuration of outgoing email sending.Read Chapter 5
Automated Remote Backups
This chapter is dedicated to implementing an automated, reliable way to create website backups. We cover how to automate backing up your site files and database. Then we dive into copying your backups to an offsite location, using Amazon S3. Finally we take a look at how to save costs for your remote backup storage, by implementing lifecycle rules that move your S3 backups to Amazon Glacier storage.Read Chapter 6
Nginx Security Hardening
Even after configuring HTTPS to encrypt connections between the browser and server, sites are still open to other areas of attack such as XSS, Clickjacking and MIME sniffing. We’ll take a look at each of those and how to deal with them. You’ll learn what a referrer policy is and how it can be useful.Read Chapter 7
Migrating WordPress to a New Server
Once you have your server up and running, the first thing you’re likely to want to do is move an existing site over to it from elsewhere. In this chapter we walk through copying the site files, Nginx configs, and SSL certificates. Next we export the database and import the database. Then we test the site on the new server before flipping the switch.Read Chapter 8
Monitoring and Ongoing Maintenance
In this chapter we walk through setting up server monitoring and alerting on DigitalOcean. We discuss how to investigate problems when you get an alert. Then we emphasize the importance of keeping plugins and themes up-to-date, checking that backups are actually running, and watching log files for problems. Finally we walk through updating server software and upgrading PHP to a new major version.Read Chapter 9
Complete Nginx Configuration Kit for WordPress
In this final chapter, we offer a complete Nginx configuration optimized for WordPress sites. Not only does it amalgamate all the information from the previous chapters, but we also draw upon the best practices from our experience over the years.Read Chapter 10