We previously used WordOps to manage WordPress/WooCommerce installations. However, in 2021 we faced several issues:
- It is often down due to high CPU usage, then exhausted CPU burst capacity.
- It does not support AWS Graviton2 instances.
Now we are switching to RunCloud with OpenLiteSpeed. Hendy evaluated Webinoly and ServerPilot ($5/month + $0.5/app/month) and SpinupWP, RunCloud ($8-$15-$45/mo), Ploi, and GridPane.
Installation
Create and set up an Ubuntu VM.
- Create AWS Lightsail instance (1 GiB for one site, 2 GiB for two or more sites), using Ubuntu latest LTS version.
- Create static IP address, and assign to the Lightsail instance.
- Using AWS Lightsail Firewall, deny HTTP port 80 and allow HTTPS port 443.
- SSH to Ubuntu
- Enable Byobu:
byobu-enable
- Install WordOps:
wget -qO wo wops.cc && sudo bash wo
Preparing WordOps Configuration
WordOps configuration, include application level debugging, is available at /etc/wo/wo.conf
.
The most important one is remote MySQL/MariaDB database configuration, as we are using AWS RDS MariaDB.
Install MySQL client (for AWS Graviton2, see #392): sudo wo stack install --mysqlclient
Edit MySQL client configuration at /etc/mysql/mariadb.conf.d/50-clients.cnf
(new WordOps uses MariaDB), or previously /etc/mysql/conf.d/my.cnf
: (change the host and password)
[client]
host = ***.ap-southeast-1.rds.amazonaws.com
user = root
password = your-very-strong-password
Edit /etc/wo/wo.conf
. Edit the [mysql]
section, set grant-host
to %
:
[mysql]
### MySQL database grant host name
grant-host = %
### Ask for MySQL db name while site creation
db-name = False
### Ask for MySQL user name while site creation
db-user = False
Edit the section and set
version
to latest stable PHP as follows:
### Default PHP version
version = 7.4
Creating A WordPress Site
Before you start, make sure you install acme.sh, then configure DNS verification, e.g. CloudFlare.
# Dedicated shell
sudo bash
# install acme.sh
curl https://get.acme.sh | sh -s email=YOUR_EMAIL
sudo -E acme.sh --register-account -m YOUR_EMAIL
export CF_Key="..."
export CF_Email="[email protected]"
# Now you can enable SSL cert
We’re using AWS RDS MariaDB, the GRANT patch was accepted.
Create the WordOps Dashboard site first: (AWS Graviton2 problem #393)
sudo -E wo stack install --dashboard
# FIXME: --netdata errors in AWS Graviton2
#sudo -E wo stack install --dashboard --netdata
sudo -E wo site create server-cname.domain.tld -le --dns=dns_cf
Trying to install –netdata will give error:
# sudo -E wo stack install --netdata
Downloading Netdata [Done]
Installing Netdata [OK]
Traceback (most recent call last):
File "/usr/local/bin/wo", line 8, in <module>
sys.exit(main())
File "/opt/wo/lib/python3.8/site-packages/wo/cli/main.py", line 102, in main
app.run()
File "/opt/wo/lib/python3.8/site-packages/cement/core/foundation.py", line 882, in run
return_val = self.controller._dispatch()
File "/opt/wo/lib/python3.8/site-packages/cement/core/controller.py", line 471, in _dispatch
return func()
File "/opt/wo/lib/python3.8/site-packages/cement/core/controller.py", line 477, in _dispatch
return func()
File "/opt/wo/lib/python3.8/site-packages/wo/cli/plugins/stack.py", line 537, in install
post_pref(self, [], packages)
File "/opt/wo/lib/python3.8/site-packages/wo/cli/plugins/stack_pref.py", line 1414, in post_pref
.format(wo_netdata),
UnboundLocalError: local variable 'wo_netdata' referenced before assignment
Then create a WordPress site:
sudo -E wo site create subdomain.lovia.life --wpredis --php74 --letsencrypt=on --dns=dns_cf --user sysadmin --email [email protected]
Crontab using WP-CLI cron
Edit the crontab for user www-data:
sudo crontab -e -u www-data
# Repeat for each website
*/5 * * * * cd /var/www/example.com/htdocs; wp cron event run --due-now > /dev/null 2>&1
Reference: https://easyengine.io/tutorials/wordpress/wp-cron-crontab/
Moving A WordOps Site to Another Server
- Backup using UpdraftPlus to AWS S3
- Install WordOps (as above)
- Prepare WordOps configuration (as above)
- Create the WordPress site with DNS verification and AWS RDS MariaDB GRANT patch (as above)
- Change the DNS record or CloudFront to point to new server
Option 1: rsync way (old database)
- On new server, using root, generate ssh-keygen
- Add key to old server’s authorized_keys
- In new server, sudo su, then rsync -va from old server:
/etc/wo/*
/var/lib/wo/*
/etc/letsencrypt/live/*
/var/www/* - Remove key from old server’s authorized_keys
- Install wo on new server
- Install stack
sudo -E wo stack install –nginx –php74 –wpcli –nginx –mysqlclient –dashboard –netdata - rsync -va from old server:
/etc/nginx/sites-available/*
# (Optional) Update LetsEncrypt certificates using Cloudflare:
#export CF_Key=....
#export CF_Email=....
#sudo -E wo site update -le wildcard --dns dns_cf yoursite.com
# What you must do is to enable each site one by one, for all sites
sudo -E wo site enable lovia.life
Enable HTTP/2 for health check: Edit /etc/nginx/sites-enabled/default.
- Uncomment the listen part including snakeoil self-signed certificate
- In the two listen lines, after “ssl” append “http2”
Snakeoil cert is:
- /etc/ssl/certs/ssl-cert-snakeoil.pem
- /etc/ssl/private/ssl-cert-snakeoil.key
sudo apt -y install ssl-cert
sudo make-ssl-cert generate-default-snakeoil
Make sure nginx default page works, at least for ALB health check:
# WordOps does not support HTTP/2 on port 80
curl -v --header 'Host: 10.0.0.1' http://172.26.10.83/
# This will be self signed cert
curl -v --http2 --insecure --header 'Host: 10.0.0.1' https://172.26.10.83/
Now we need to set up crontab, see Crontab section below.
Cleanup old server:
- Remove all WordPress files from old server:
sudo wo site delete --files subdomain.example.com
In MariaDB, drop the “new” (unused) WordPress database and user
Option 2: UpdraftPlus way (new database)
- Copy parts of the wp-config.php file (SES config, etc.)
- Sign in to new WordPress
- Install UpdraftPlus
- Link AWS S3
- Restore from AWS S3 backup
- Delete old site
Operations
Update WordOps
sudo -E wo update
Perform Maintenance
sudo -E wo maintenance
Upgrade Stack
This is needed to upgrade files like /etc/nginx/common/wpcommon-php74.conf
and others.
sudo -E wo stack upgrade
Performance Best Practices
Although WordOps is good by default, Hendy found a few ways that can be optimized, with caveats.
Buffering access_log
By default all sites will write access_log all the time, even just for BetterUptime monitoring. So, edit /etc/nginx/sites-available/* and enable buffering, e.g.:
access_log /var/log/nginx/22222.access.log rt_cache buffer=32k;
How to Change WordPress Site URL using WP CLI
cd /var/www/anakalam.id/htdocs
sudo -u www-data wp search-replace 'https://anakalam.id' 'https://www.anakalam.id' --skip-columns=guid
sudo -u www-data wp cache flush