Page load speed is on everyone’s mind. Rightfully so, as many tests have proven how important page speed is for conversion and reduction of bounce rate.
In March 2018, LiteSpeed did a benchmark test comparing OLS, NGiNX and Apache. The results compellingly reveal that OLS is capable of handling more requests faster than either of the other two web servers. What is more, there is a standing open invitation for anybody to try any configuration they choose against OLS. Even so, Apache (released 1995) and NGiNX (released 4 October 2004) still have more than double the market share OLS (released 1 July 2003) has.
In this article, I will show you how I set up an OLS server on an AWS Lightsail instance with Ubuntu 18.04. AWS also has an Ubuntu 20.04 + OLS + WordPress image which can simply be deployed on Amazon EC2 without going through these steps.
Create an Ubuntu 18.04 LTS Instance in AWS Lightsail
To begin, we will launch an AWS Lightsail instance that only contains Ubuntu 18.04 LTS from the Lightsail dashboard.
The first section of the Lightsail instance setup page allows you to select a geographical region in which we want the instance hosted. This will depend on the closest location to where the primary source of traffic for the website will be.
The second section is a selection of images that are available for installation on the instance. It defaults to the “Apps + OS” tab with the Bitnami WordPress single site image selected. We will change that to the “OS Only” tab and select Ubuntu 18.04 LTS. Any of the other OSs will work, but I will only focus on Ubuntu here.
The third section is a selection of instance price plans (excluding tax). The selection will depend on the requirements of the site. A brand new site with very little traffic could work on the lowest price plan and upgrade as needed, whereas a bigger, more established site with more traffic would need to choose the appropriate resources it may need.
Once these choices have been made, the defaults for the rest will be fine. We can create the instance.
Optional: Upgrade Ubuntu
OLS works great on Ubuntu 20.04 LTS. Upgrade Ubuntu 16.04 LTS to Ubuntu 18.04 LTS, or upgrade Ubuntu 18.04 LTS to Ubuntu 20.04 LTS.
Set Up Lightsail Instance IP and Firewall Ports
While we are in the Lightsail control panel, we will create a static IP for our instance, and set up the firewall ports for the instance to work.
The public IP initially assigned to the instance is a shared IP that may change each time the instance is restarted. We want the IP to stay the same at all times so that the DNS will resolve correctly.
In the instance we just created, we will go to the “Networking” tab. In the “Public IP” block, we will click on “Create static IP.” This will take us to an options page where we can select for which region we are creating the IP, and which instance we want to attach it to. A static IP that is not connected to an instance will be billed, whereas a static IP connected to an instance is free.
We will go ahead and create the static IP and attach it to the instance we created in the previous step. Once done, we will head back to the instance’s “Networking” tab to modify the firewall rules.
By default only TCP ports 22 and 80 are open. We will open TCP ports 443 and 7080, as well as UDP port 443. We’ll do this by clicking on “Add rule” and completing the necessary information.
The ports are for:
- TCP 22: SSH connections to the server (this port rule can be deleted once all settings have been changed, but it is not necessary to do so, since a connection needs keys)
- TCP 80: Normal traffic over HTTP
- TCP 443: Secure traffic over HTTPS
- TCP 7080: OLS default port for the web administration interface (this port rule should be deleted once all settings have been changed, since the login is password-based)
- UDP 443: Secure traffic over HTTP/3
Configure Domain DNS
Our instance has a static IP address, which is what we will point our domain to.
In the DNS manager of the domain, change the domain’s A record to the static IP created earlier. It will look similar to this:
Prepare Usernames and Passwords
We are going to use the one-click-install option for OLS, so it will be necessary to have usernames and passwords ready to paste into the command we will run through the SSH terminal. I like to use Random.org (opens in new tab) to generate both usernames and passwords.
We will need:
- A password for the OLS webAdmin page
- An e-mail address for the OLS webAdmin page
- A password for the root MariaDB user
- A name for the WordPress database
- A username for the WordPress database
- A password for the WordPress database user
- A username for the WordPress user (to log in to WordPress)
- A password for the WordPress user (to log in to WordPress)
LiteSpeed Enterprise Web Server is free for one domain on one VPS.
Connect Using SSH and Install OLS
In the Lightsail dashboard, we will connect to the instance using Lightsail’s browser SSH to perform various tasks through the terminal. You could also connect using Putty, as described in the Lightsail documentation.
I’ll first break down what we are going to do, before giving you one long command to copy.
I like to work in the temporary folder for installations. With this command, we switch to that folder.
cd /tmp
We will download the command script for the OLS 1-Click Installation to the temporary folder.
wget --no-check-certificate https://raw.githubusercontent.com/litespeedtech/ols1clk/master/ols1clk.sh
We will pass the parameters to the OLS 1-Click Installation and run the setup script.
sudo bash ols1clk.sh -a "[webAdmin Password]" -e [webAdmin User e-Mail] --lsphp 74 --wordpressplus [domain] --wordpresspath /usr/local/lsws/wordpress/html -r "[MariaDB Root Password]" --dbname [Database Name] --dbuser [WordPress Database Username] --dbpassword "[WordPress Database User Password]" --listenport 80 --wpuser [WordPress User Login Name] --wppassword "[WordPress User Password]" --wplang en_US --sitetitle "[WordPress Site Name]"
Replace the sections between [ and ] with the appropriate information we collected earlier, so it will become something similar to:
sudo bash ols1clk.sh -a "8WM6GfHy" -e [email protected] --lsphp 74 --wordpressplus fouriemc.com --wordpresspath /usr/local/lsws/wordpress/html -r "KCeBURs7" --dbname demo_wordpress --dbuser HzdPQ8NR --dbpassword "xYGn8faT" --listenport 80 --wpuser PxW6gf2S --wppassword "jZEV5WXc" --wplang en_US --sitetitle "Demo OLS Setup"
We will remove the OLS 1-Click Installation script file from the temporary folder.
rm ols1clk.sh
All the above in one string:
cd /tmp && wget --no-check-certificate https://raw.githubusercontent.com/litespeedtech/ols1clk/master/ols1clk.sh && sudo bash ols1clk.sh -a "[webAdmin Password]" -e [webAdmin User e-Mail] --lsphp 74 --wordpressplus [domain] --wordpresspath /usr/local/lsws/wordpress/html -r "[MariaDB Root Password]" --dbname [Database Name] --dbuser [WordPress Database Username] --dbpassword "[WordPress Database User Password]" --listenport 80 --wpuser [WordPress User Login Name] --wppassword "[WordPress User Password]" --wplang en_US --sitetitle "[WordPress Site Name]" && rm ols1clk.sh
The OLS Installation script will display one verification prompt to ensure the information is correct before proceeding with a series of actions.
Once the installation is complete, you will be returned to the command prompt.
(Note: these settings were specifically created for this article. The usernames and passwords are not connected to any live site, and the IP‘s have long been discarded. Never post active usernames, passwords or IP‘s on the internet.)
Installing Certbot and Obtaining a Let’s Encrypt Certificate
There are several ways to configure Certbot to verify a domain. I will demonstrate the webroot authentication method, as well as the Cloudflare authentication method. In both cases, you will be prompted to enter your e-mail address (required), agree to the Let’s Encrypt terms (required) and have the option to allow being added to a marketing list (it’s safe to say no – it won’t affect whether a certificate is issued or not.)
First, we will install Certbot with this command.
sudo apt-get install -y software-properties-common certbot
With the webroot method, we will tell Certbot where our webroot is and which domains are linked to it. Certbot will use this information to request a Let’s Encrypt security certificate. (Replace example.com with your own domain and adjust as needed.)
sudo certbot certonly --webroot -w /usr/local/lsws/wordpress/html -d example.com -d www.example.com
With the Cloudflare method, we need to install an additional module and create a configuration file before running Certbot.
Your Cloudflare Global API Key can be found in the Cloudflare Dashboard (opens in new window).
Certbot will pass the information to Let’s Encrypt, which will generate DNS entries in Cloudflare, attempt to read them, and if successful, delete them and issue a certificate. This method is useful to generate a certificate for a domain that is not yet being served from the server.
Run each line as a separate terminal command.
sudo apt-get install -y python3-certbot-dns-cloudflare
mkdir ~/.secrets && mkdir ~/.secrets/certbot && echo 'dns_cloudflare_email = [Cloudflare Login e-Mail]' >> ~/.secrets/certbot/cloudflare.ini && echo 'dns_cloudflare_api_key = [Global API Key]' >> ~/.secrets/certbot/cloudflare.ini && chmod 600 ~/.secrets/certbot/cloudflare.ini
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d example.com -d www.example.com
In both cases, the certificate files will be stored at:
/etc/letsencrypt/live/example.com/privkey.pem
/etc/letsencrypt/live/example.com/fullchain.pem
(If multiple domains are passed, the certificate will be placed under the name for the first domain and contain the certificates for all the other domains. For example, example1.com, example2.com and example3.com could all be contained in the certificate files under /etc/letsencrypt/live/example1.com/)
The certificates will automatically be renewed through a cron job Certbot will create during installation.
It is necessary to adjust OLS to use these certificate files so that it can serve the website through HTTPS.
Setting Up OLS To Use Security Certificates
The OLS webAdmin is located at either:
https://your-domain.com:7080 or https://[serverIP]:7080
The default username is ‘admin’ and the password will be what you set it to be earlier during setup.
Once logged in, you will navigate to Listeners -> WordPressSSL -> SSL
Click on the ‘Edit’ button and enter the information to resemble the following image.
Once saved, a notification will appear that says “Configuration has been modified. To apply changes, please perform a graceful restart.”
To perform a graceful restart, click on the green button with the circular arrow. A confirmation notice will appear, and OLS will restart after a couple of seconds if confirmed.
Adjusting LSAPI PHP Memory Limits
While still in the OLS webAdmin interface, we will adjust the LSAPI PHP memory limit settings by going to Server Configuration -> External App and editing the entry under type “LiteSpeed SAPI App.” Within the options, there are four settings we are interested in: “Memory Soft Limit (bytes)”, “Memory Hard Limit (bytes)”, “Process Soft Limit” and “Process Hard Limit”.
The defaults are for a machine with 4GB RAM. Adjust them as needed for your setup. Eg. a machine with 512MB RAM is 8 times smaller, so the settings would be divided by 8 to arrive at the best setting for your machine.
Once saved, another graceful restart is required for the settings to take effect.
Installing WP–CLI
I use WP–CLI to take care of WordPress cron jobs, which is better for performance than the default WordPress cron system.
We will run a command to install everything in one.
sudo apt-get install -y lsphp74-imagick && sudo wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && sudo chmod +x wp-cli.phar && sudo mv wp-cli.phar /usr/local/bin/wp && sudo sed -i 's\games"\games:/usr/local/lsws/lsphp74/bin/"\' /etc/environment && source /etc/environment && sudo killall -9 lsphp
File Permissions and Ownership
To ensure that all files can be written to by WordPress, WP–CLI and myself through SFTP, we will run the following command to set the file permissions and ownership. Adjust it as needed for where you chose your WordPress files to be installed.
sudo chown -hR ubuntu:ubuntu /usr/local/lsws/wordpress && sudo find /usr/local/lsws/wordpress/html -type d -exec chmod 775 {} \; && sudo find /usr/local/lsws/wordpress/html -type f -exec chmod 664 {} \;
Enhancing Security
The default OLS installation doesn’t set WordPress up securely enough for my liking. We will add salts, adjust some WordPress settings, install a security plugin, install an SMTP plugin (since Lightsail instances don’t provide outgoing mail) and move the WordPress configuration file outside of the webroot folder.
wp config shuffle-salts --path=/usr/local/lsws/wordpress/html && wp config set DISALLOW_FILE_EDIT true --raw --path=/usr/local/lsws/wordpress/html && wp config set FORCE_SSL_ADMIN true --raw --path=/usr/local/lsws/wordpress/html && wp config set FORCE_SSL_LOGIN true --raw --path=/usr/local/lsws/wordpress/html && wp config set AUTOMATIC_UPDATER_DISABLED true --raw --path=/usr/local/lsws/wordpress/html && wp plugin install wordfence wp-mail-smtp --path=/usr/local/lsws/wordpress/html --activate --quiet && mv /usr/local/lsws/wordpress/html/wp-config.php /usr/local/lsws/wordpress/wp-config.php
Setting Up Cron Jobs
WordPress uses a cron system to take care of maintenance tasks. Unfortunately, WordPress has to cater for a wide variety of situations. For that reason, each time a page is loaded, WordPress will check whether there are any scheduled tasks to run, and if there are, run them. This is unnecessary and can slow down a site.
We will disable the default WP-Cron and enable a system cron to run WP-Cron once every minute, instead of each time a page is loaded.
Since we installed WP–CLI, we will use it to disable WP-Cron from the command line with this command:
wp config set DISABLE_WP_CRON true --raw --path=/usr/local/lsws/wordpress/html
We will create a system cron file named “wordpress” while adding a cron job every minute to the system cron file we created from the command line, so that you don’t have to edit any files manually. You could also set it to run once every 5 minutes by replacing */1 with */5 depending on your preference.
sudo sh -c "echo 'SHELL=/bin/sh' >> /etc/cron.d/wordpress" && sudo sed -i -e '$ a\PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/lsws/lsphp74/bin/' -e '$ a\1 * * * * ubuntu wp cron event run --due-now --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' /etc/cron.d/wordpress
I use several other cron commands on my installation to update both WordPress and the system. You’re welcome to add them to yours as well, or to modify them to your needs. We will use SEd to insert these commands from the command line, so that you don’t have to edit any files.
sudo sed -i -e '$ a\0 0 * * * root wp cli update --yes >/dev/null 2>&1' -e '$ a\5 0 * * * ubuntu wp plugin update --all --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\10 0 * * * ubuntu wp language plugin update --all --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\15 0 * * * ubuntu wp theme update --all --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\20 0 * * * ubuntu wp language theme update --all --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\25 0 * * * ubuntu wp core update --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\30 0 * * * ubuntu wp language core update --path=/usr/local/lsws/wordpress/html --quiet >/dev/null 2>&1' -e '$ a\2 4 * * 1 root apt update && DEBIAN_FRONTEND=noninteractive apt -o Dpkg::Options::="--force-confold,confdef" -y full-upgrade && apt clean && shutdown -r > /dev/null 2>&1' -e '$ a\0 2 * */3 * ubuntu wp config shuffle-salts --path=/usr/local/lsws/wordpress/html >/dev/null 2>&1' /etc/cron.d/wordpress
Changing PHP Defaults
The default PHP settings are overly restrictive in some areas. We will edit them from the command line using SEd, but you could also use Nano to open the file and edit it.
The syntax is:
sed -i -e 's\[old text 1]\[new text 1]\g' -e 's\[old text 2]\[new text 2]\g' file.name
I will only change these three settings, but you may want to edit some other PHP settings.
sudo sed -i -e 's\memory_limit = 128M\memory_limit = 256M\g' -e 's\post_max_size = 8M\post_max_size = 100M\g' -e 's\upload_max_filesize = 2M\upload_max_filesize = 25M\g' /usr/local/lsws/lsphp74/etc/php/7.4/litespeed/php.ini && sudo killall -9 lsphp
Creating a Swap File
If you didn’t upgrade Ubuntu, the default system does not have any swap space. We will create a 2GB swap file, which should be sufficient for most systems. Adjust the size if necessary.
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile && sudo sed -i '$ a\/swapfile swap swap defaults 0 0' /etc/fstab
Server Updates and Reboot
At this stage, Ubuntu will have several updates to perform. We will run the following command to update all the packages on the system and reboot for them to take effect.
sudo apt update && sudo DEBIAN_FRONTEND=noninteractive apt -o Dpkg::Options::="--force-confold,confdef" -y full-upgrade && sudo apt clean && sudo shutdown -r
Conclusion
Once the server has rebooted, you’re ready to start building your site using Ubuntu, OLS and WP on AWS Lightsail.
As your site grows, you can move your instance to plans with more resources and adjust your OLS settings accordingly.
This configuration, along with the LSCWP plugin which was installed and activated during this process, will already provide a significant (and noticeable) boost to your website’s page load speed. Going through the options of the LSCWP plugin can help you further enhance its function.