The LEMP software stack consists of a group of software that describes a Linux Operating System, a Nginx web server (pronounced engine-x), and a MySQL database with the dynamic processing being handled by PHP. LEMP is an acronym for Linux, Engine-x (Nginx), MySQL and PHP.
WordOps simplifies so much of the process of installing and configuring all the packages from the LEMP stack needed to deploy a site while taking care of creating virtual hosts in Nginx, installing WordPress, and even getting you an SSL certificate.
It also installs some components that allow you to see statistics about the server’s workload.
In this tutorial, we’ll use WordOps to quickly and easily install WordPress on an Ubuntu 22.04 machine, and we’ll check out and explain some of the extra features that WordOps offers.
The primary motivation for writing this tutorial is for users who don’t feel ready to install WordPress themselves on a server.
A while ago I wanted to move from shared hosting to a DigitalOcean $5 server because I needed better performance for a smaller price. I’m not knocking on shared hosting, it was just the right choice for me at the time. The transition was a pain, however, because I didn’t have much Linux experience.
I think WordOps can be beneficial to many users who are in a similar situation, and I think it’s not as well known as it should be. It would’ve been great if I knew of such as solution when I started out.
We have also written a detailed tutorial on using a similar tool for quickly setting up WordPress sites, called SlickStack, and also EasyEngine, which uses Docker containers to manage WordPress websites and from which WordOps is forked.
Creating Websites for Beginners
If you are just beginning setting up websites you may want to check our step-by-step beginner tutorial on creating a website.
Table of Contents
- Quick Demo [Video]
- Step 1 – Download & Install WordOps
- Step 2 – Install WordPress using WordOps
- Step 3 – Installing WordOps Stacks (Optional)
- Create a Swap File
- Questions I’ve Asked Myself
Quick Demo [Video]
To get to the point early on, so you can decide if this tutorial is right for you, let’s start with a quick video demo on how we can quickly set up a WordPress website.
In this demo, I’m using a server running Ubuntu 20.04 with 2GB RAM from DigitalOcean, and I’ve set up WordPress on a personal domain https://mrtest.site. The installation should be the same on Ubuntu 22.04 with PHP 8 instead of PHP 7.4.
The entire process took only a few commands and filling out input when prompted. It took about 7 minutes, but only because of waiting for WordOps and its dependencies to be downloaded and installed. I believe this is an isolated case, in many other instances you’re done in less than 5 minutes.
That video is primarily to demonstrate how fast and easy you can set up an optimized WordPress install using WordOps.
If you’re not familiar with the options you’ve seen in that command, then I highly recommend you take just a bit of time to understand what they mean and what alternatives you have to those options, so you can configure the installation to your specific needs.
I will try to explain those options further down in this tutorial, and you definitely should check all of them in the WordOps docs. They’re laid out in a very straightforward manner.
If you’re convinced that WordOps is a good choice for you, then let’s see in a bit more detail how it can help you to manage/configure/install WordPress.
- Access to a server running Ubuntu 22.04, with at least 1GB RAM. If you plan to have a larger, more dynamic site then we recommend 2GB+ RAM
- A domain pointing to your server
- We recommend being logged in as a
non-root sudo user. This is because when you’re acting as root you run the risk of harming your system if you’re not careful.
Step 1 – Download & Install WordOps
We’ll install WordOps using the provided installer script so all the dependencies and WordOps are installed automatically.
There are also the options of cloning the repository from Github or installing it manually. If you’re interested in one of those methods, then you can find the instructions in the installation documentation.
First, we’ll update the server’s software package index:
sudo apt update
To perform the automated install, run the following command, which downloads and runs the WordOps install script.
wget -qO wo wops.cc && sudo bash wo
Sometime during the installation, you’ll be prompted for a username and an email address. Those details will only be stored locally in the .gitconfig file, and will be used for saving server configurations.
Here is my output:
Enable WordOps Auto-Completion (optional)
You can enable WordOps auto-completion, so that commands autocomplete when you write them partially and press Tab. To do this run the following command:
Creating an alias to easily use sudo wo as a non-root user (optional)
The wo command needs to be used with sudo. To easily use it without typing sudo wo every time, you can create an alias for it to always automatically add sudo in front of wo.
To do this run the following command:
echo -e "alias wo='sudo -E wo'" && $HOME/.bashrc
Step 2 – Install WordPress using WordOps
Now that WordOps is installed, you can get to setting up WordPress.
In this example, I’ll install WordPress using my domain mrtest.site, using PHP 8.1, a Let’s Encrypt SSL certificate, Nginx fastcgi_cache, and HSTS. I’ll also set my desired WordPress user/password.
To do this, I’ll run:
sudo wo site create mrtest.site --php81 --letsencrypt --wpfc --hsts --user=Ed --pass="Thisisntmyp@ssword1234_"
Here is my output for this command:
You can also leave the command without –user or –password and WordOps will automatically use your name that you set when installing it, and it will generate a random complex password that you’ll be shown when WordPress is finished installing.
If the password you’re setting contains special characters, you can put single quotes around the password, as in the example above:
Right before the installation is finished you’ll be shown the login credentials to access your WordOps backend and separate credentials to access the WP dashboard. It should look something like this:
HTTP Auth User Name: WordOps HTTP Auth Password : khT8hHVNmxK7IQ7DzYaS3dQf WordOps backend is available on https://126.96.36.199:22222 or https://mrtest.site:22222 WordPress admin user : Ed WordPress admin password : Thisisntmyp@ssword1234_
And that’s it! With just a few commands you can easily set up a solid WordPress install.
Configurable Features (Caching/SSL/PHP Versions/HSTS)
WordOps enables you to install WordPress and configure it with a few popular features, such as:
- Multiple cache mechanisms: NO Cache, WP Super Cache plugin, Nginx fastcgi_cache, Redis cache, WP-Rocket plugin , Cache-Enabler plugin
- SSL certificates with Let’s Encrypt for your domain, subdomain, and also Wildcard SSL
- Issuing Let’s Encrypt certificates with DNS validation – such as when you have CloudFlare enabled
- Multiple versions of PHP – 8, 8.1
- Enabling HSTS, which basically forces all connections to use HTTPS. To learn more about this, you can check out this really nice article from GlobalSign and this one from mozilla.org
To perform website specific actions, you can use the wo site command. The structure of this command is:
sudo wo site (command) [options]
To create a website, we use the wo site create command. The structure of this command is:
sudo wo site create [<yourdomain.tld>] [options]
I’m not going to get into all the configurations, since the docs have a comprehensive list already, but I’ll give a few examples since you’re already here, to give you an idea:
# standard WordPress site sudo wo site create yoursite.com --wp # WordPress site + Nginx fastcgi_cache sudo wo site create yoursite.com --wpfc # WordPress site + WP Super Cache & Nginx properly configured to work with it sudo wo site create yoursite.com --wpsc # WordPress site + WP-Rocket & Nginx properly configured to work with it sudo wo site create yoursite.com --wprocket # WordPress site + Cache-Enabler plugin & Nginx properly configured to work with it sudo wo site create yoursite.com --wpce # WordPress site + Redis Cache & Nginx properly configured to work with it sudo wo site create yoursite.com --wpredis # WordPress site + WP Super Cache & Nginx properly configured to work with it + Let’s Encrypt SSL sudo wo site create yoursite.com --wpsc --letsencrypt # WordPress site + WP-Rocket & Nginx properly configured to work with it + Let’s Encrypt SSL + PHP 8.1 sudo wo site create yoursite.com --wpsc --letsencrypt --php81 # WordPress site + Nginx fastcgi_cache & Nginx properly configured to work with it + Let’s Encrypt SSL + PHP 8.1 + HSTS Enabled sudo wo site create yoursite.com --wpsc --letsencrypt --php81 --hsts
Step 3 – Installing WordOps Stacks (Optional)
The WordOps stacks are basically additional software packages that help you manage your server.
You install all the recommended software packages by running the following command:
sudo wo stack install
The components that will be installed are:
Nginx – WordOps web server
PHP 8.1 – PHP8.1-FPM
MariaDB 10.5 – Open-source version of MySQL
WP-CLI – The WordPress command-line tool
Composer – PHP packages manager
MySQLTuner – Command-line tool to tune MySQL
Fail2ban – Authentication bruteforce protection
phpMyAdmin – MySQL server web interface
Adminer – lightweight phpMyAdmin alternative
OpcacheGUI – web interface for Opcache monitoring
Netdata – Monitoring suite
Anemometer – MySQL Slow Query Monitor
WordOps dashboard – Bootstrap template for WordOps backend
eXtplorer – Web File manager
cheat.sh – Command-line Linux cheatsheet
Sendmail – Sendmail MTA
It would look something like this:
After that, you should be able to access the WordOps dashboard in your browser, which you can access by visiting https://your_ip:22222 or https://yourhostname:22222. You’ll be presented with an authentication prompt where you can enter your WordOps username/password.
Here’s a very quick preview of the WordOps dashboard:
For more on the stack command, you can read this article from the WordOps docs: https://docs.wordops.net/commands/stack/
Create a Swap File
A swap file is a section of hard disk used as virtual memory. When the memory on your computer gets full, any new information you try to put in it is put on the swap file instead. When you need the information, you can “swap“ it back into memory.
Based on my experience with hosting WordPress sites on small VPS, I’ve noticed significant improvements after adding swap space. If you don’t have swap space added, you’re seeing high RAM usage, and are often seeing database errors displayed by WordPress when visiting your website, then you might want to create a swap file.
Typically, swap space should be double the amount of RAM. So if we have a server with 1GB RAM, we’ll set up 2GB swap space.
Check Swap Information
First, let’s check if we have a swap file. We can do this in two ways:
Run the following command. If you see no output, you most likely don’t have any swap space added.
sudo swapon --show
If you have swap space, it would look something like this:
NAME TYPE SIZE USED PRIO /swapfile file 1.9G 330.7M -2
Another way you can check is by running:
If you don’t have swap space, you’ll see
0B on the Swap line:
total used free shared buff/cache available Mem: 981Mi 512Mi 170Mi 115Mi 299Mi 158Mi Swap: 0B 0B 0B
If you have swap space added, it would look something like:
total used free shared buff/cache available Mem: 981Mi 286Mi 279Mi 64Mi 414Mi 417Mi Swap: 1.9Gi 330Mi 1.5Gi
How to Create a Swap File
We’ll add 2GB of swap space to our server. If you’d prefer a different amount, just replace
3G and so on, in the following command:
sudo fallocate -l 2G /swapfile
If you don’t have
fallocate available on your system, then you can create the file with the following command, replacing
2048 with the number of megabytes you want; for 1GB use
1024, for 3GB, use
3072, and so on.
sudo dd if=/dev/zero of=swapfile bs=2048 count=1048576
Next, set permissions so only the root user can write and read the swap file:
sudo chmod 600 /swapfile
Now, we’ll use the
mkswap utility to set up the file as Linux swap space:
sudo mkswap /swapfile
We’ll enable the swap by running:
sudo swapon /swapfile
Finally, to make the change permanent, we’ll open a file called
/etc/fstab and add the following line:
/swapfile swap swap defaults 0 0
That’s it. Now you can check using the commands mentioned above and you should see swap being active.
Questions I’ve Asked Myself
Not an ideal title for this section – I would’ve preferred to have a FAQ section, but I don’t know if these are frequently asked.
These are just questions I’ve had myself and I hope some may help you. If you have any other questions that you can’t find an answer to, then please feel free to leave them in the comments or contact us.
You can also check the WordOps FAQ for more info.
Why is WordOps better than regular WordPress + Nginx?
I don’t know all of the advantages, and I don’t know any disadvantages, but here are my reasons for using WordOps:
- Fast WordPress Install: I used to set up WordPress + Nginx myself manually, or automated via some scripts. But it would be a quick and dirty solution – nowhere near how WordOps does it, with all the additional features, ready made configurations, and security.
- CLI: Simple and intuitive command-line utility to easily manage sites.
- Secure: Already secured by knowledgeable developers, and I can add extra layers of security if I want.
- Caching Plugins Configured for Nginx: Automatically configured Nginx for several caching plugins. I believe that most of these caching plugins require you to make extra configurations when using them with Nginx, instead of Apache. WordOps automatically configures those caching plugins, so you don’t have to.
- Simple Documentation: I find the docs to be uncomplicated and beginner friendly.
- Active/Helpful Community: If you have questions or issues you can’t find a solution to you can just ask here https://community.wordops.net. It’s very welcoming and easy to navigate, in my opinion.
Why is it important that WordOps also installs caching plugins? Can’t I simply install them myself?
Some popular caching plugins may require configuring Nginx so they can work. WordOps does that for you, so you don’t have to bother finding the correct way to configure them.
What is HSTS and why does it matter?
HSTS (HTTP Strict Transport Security) is a policy that you can enable, which basically makes your website declare that it can only be accessed via HTTPS.
This isn’t enabled by default when you set up SSL for your website, and your website will have a 301 redirect from HTTP to HTTPS, which makes it significantly weaker, as it presents a window of opportunity for potential hackers to use downgrade attacks on your users.
If you’d like to better understand HSTS, I recommend this article from mozilla.org
What is Fail2Ban?
Fail2Ban is a tool that helps prevent unauthorized access to both your server and your WordPress install. It notes failed login attempts, and based on a set of rules (that you can adjust), it bans those IPs by modifying the server’s firewall rules.
This helps, as your server and site often deals with login attempts from bots. At least, my sites do.
I use Simple History, a plugin to easily log recent changes and such, and here’s the latest attempts I’m seeing at the time of writing (March 4th, 2021)
The “similar events” are failed login attempts.
Why use WordOps over EasyEngine?
WordOps is a fork of the previous version of EasyEngine (version 3). The current version of EasyEngine (version 4) uses Docker.
The reason I prefer WordOps is that I’m not familiar enough with Docker.
Additionally, EasyEngine’s community and support don’t seem to be very active, and if I run into issues, it’s difficult to find solutions online. I’ve tried it for a year for development websites, where I’d test things, but when I ran into an issue, I couldn’t find a solution, so I switched to WordOps which has an active community.
Does WordOps work with W3 Total Cache?
WordOps doesn’t have a configuration for W3 Total Cache, like it has for the other caching plugins. From what I understand, support for W3TC was dropped as a security precaution when they forked WordOps from EasyEngine v3.
I don’t know the reason behind it however – I suspect W3TC had some security issues at the time. [Link to Discussion Thread on WordOps Community Forum]
I believe you can configure Nginx to work with W3 Total Cache yourself, but I haven’t tried it myself. If you’re adamant about using WordOps with W3TC then I’d suggest consulting with the WordOps community at https://community.wordops.net
Your domain is properly configured, but acme.sh was unable to issue a certificate.
Perhaps you’ve encountered this error:
Your domain is properly configured but acme.sh was unable to issue certificate. You can find more informations in /var/log/wo/wordops.log
This error may be caused by various reasons. I’ve tried the solutions suggested on the WordOps forum, but what worked for me was disabling my firewall (which was the last issue I expected).
In my case, I just ran:
sudo ufw disable
And ran the command to update my site with Lets Encrypt.
sudo wo site update yoursite.com -le --force
And it worked.
Then, I just re-enabled the firewall.
sudo ufw enable
Your situation may differ – you may have a different issue or a different firewall. This was the issue in my case.