• This field is for validation purposes and should be left unchanged.
  • LET'S TALK!

    Fill in the form below to make an enquiry or find my contact details on my contact page.

Freelance WordPress Developer

Deploy WordPress on AWS EC2 with OpenLiteSpeed, SSL, and Maximum Security

Complete Guide: Deploy WordPress on AWS EC2 with OpenLiteSpeed, SSL, and Maximum Security

A comprehensive tutorial for setting up a production-ready WordPress site on AWS with OpenLiteSpeed web server, free SSL, Redis caching, and enterprise-level security.

Total Time: 60-90 minutes
Cost: £0/month (6 months AWS free tier)
Difficulty: Intermediate


What You’ll Build

By the end of this guide, you’ll have a fully optimized WordPress site with:

✅ AWS EC2 server (London region for UK/EU speed)
✅ OpenLiteSpeed web server (faster than Apache/Nginx)
✅ Free SSL certificate (Let’s Encrypt)
✅ Redis object caching (database optimization)
✅ A+ security rating (headers, firewall, fail2ban)
✅ Email functionality (Brevo SMTP)
✅ HTTP/2 and HTTP/3 support
✅ Automatic security updates


Prerequisites

AWS Account – free tier eligible
Domain name – example.com, pointed to AWS after setup
SSH client – Terminal on Mac/Linux, PuTTY on Windows
Basic command line knowledge
WordPress backup – files + database export if migrating existing site


Part 1: Launch AWS EC2 Instance

Step 1.1: Create EC2 Instance

Log into AWS Console and navigate to EC2. Click “Launch Instance”.

Configure instance:

Name: example.com

Application and OS Images (AMI):
Select “Ubuntu”
Choose “Ubuntu Server 24.04 LTS (HVM), SSD Volume Type”
Verify “Free tier eligible” badge

Instance type: t3.micro (1 vCPU, 1GB RAM – free tier)

Key pair (login):
Click “Create new key pair”
Name: wordpress-key
Type: RSA
Format: .pem (Mac/Linux) or .ppk (Windows)
Download and save – you need this to connect!

Network settings:
Click “Edit”
Security group name: wordpress-sg

Add these rules:
SSH (22) – Source: My IP
HTTP (80) – Source: Anywhere (0.0.0.0/0)
HTTPS (443) – Source: Anywhere (0.0.0.0/0)
Custom TCP (7080) – Source: My IP (for WebAdmin)

Configure storage: 30 GiB (free tier includes up to 30GB)

Click “Launch Instance”

Get your Public IP:
Go to Instances
Select your instance
Copy “Public IPv4 address” (e.g., 18.133.138.227)


Step 1.2: Connect to Your Server

Mac/Linux:

#Navigate to where your key was downloaded
cd ~/Downloads
#Set correct permissions
chmod 400 wordpress-key.pem
#Connect (replace YOUR-IP with your instance's public IP)
ssh -i wordpress-key.pem ubuntu@YOUR-IP 

Windows (PowerShell):

 ssh -i C:\Users\YourName\Downloads\wordpress-key.pem ubuntu@YOUR-IP 

First connection: Type yes when asked to continue.

You should now see: ubuntu@ip-xxx-xxx-xxx-xxx:~$ ✅


Part 2: Install OpenLiteSpeed & Dependencies

Step 2.1: Update System

 sudo apt update && sudo apt upgrade -y

Step 2.2: Add OpenLiteSpeed Repository

 wget -O - https://repo.litespeed.sh | sudo bash sudo apt update 

Step 2.3: Install OpenLiteSpeed + PHP 8.3

 sudo apt install openlitespeed lsphp83 lsphp83-common lsphp83-mysql lsphp83-curl lsphp83-opcache lsphp83-intl lsphp83-imap lsphp83-pspell lsphp83-sqlite3 lsphp83-tidy lsphp83-redis -y 

Step 2.4: Install MariaDB (Database)

 sudo apt install mariadb-server -y 

Step 2.5: Start Services

 
sudo systemctl start lsws 
sudo systemctl enable lsws 
sudo systemctl start mariadb 
sudo systemctl enable mariadb 

Step 2.6: Create PHP Symlink

 sudo ln -sf /usr/local/lsws/lsphp83/bin/php /usr/bin/php 

Step 2.7: Test OpenLiteSpeed

In browser, visit: http://YOUR-IP:8088

You should see the OpenLiteSpeed welcome page! ✅


Part 3: Configure OpenLiteSpeed for WordPress

Step 3.1: Set WebAdmin Password

 sudo /usr/local/lsws/admin/misc/admpass.sh 

Enter username: admin
Enter password: create strong password

Save these credentials!

Step 3.2: Create Virtual Host Directory Structure

 
sudo mkdir -p /usr/local/lsws/example.com/html 
sudo mkdir -p /usr/local/lsws/example.com/logs 
sudo mkdir -p /usr/local/lsws/conf/vhosts/example.com 

Step 3.3: Create Virtual Host Configuration

 

docRoot $VH_ROOT/html
vhDomain example.com, www.example.com
vhAliases example.com, www.example.com
enableGzip 1
enableIpGeo 1

errorlog $VH_ROOT/logs/error.log {
  useServer 0
  logLevel ERROR
  rollingSize 10M
}

accesslog $VH_ROOT/logs/access.log {
  useServer 0
  logFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
  logHeaders 5
  rollingSize 10M
  keepDays 30
  compressArchive 1
}

index {
  useServer 0
  indexFiles index.php, index.html
}

scripthandler {
  add lsapi:lsphp83 php
}

extprocessor lsphp83 {
  type lsapi
  address uds://tmp/lshttpd/lsphp.sock
  maxConns 35
  env PHP_LSAPI_CHILDREN=35
  env LSAPI_AVOID_FORK=200M
  initTimeout 60
  retryTimeout 0
  persistConn 1
  respBuffer 0
  autoStart 2
  path $SERVER_ROOT/lsphp83/bin/lsphp
  backlog 100
  instances 1
  priority 0
  memSoftLimit 2047M
  memHardLimit 2047M
  procSoftLimit 1400
  procHardLimit 1500
}

rewrite {
  enable 1
  autoLoadHtaccess 1
  
  rules <<<END_rules
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
END_rules
}

context / {
  location $DOC_ROOT/
  allowBrowse 1
  rewrite {
    enable 1
    inherit 1
  }
  
  addDefaultCharset off
  extraHeaders <<<END_extraHeaders
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
END_extraHeaders
  
  phpIniOverride {
    php_admin_value engine On
  }
}

context /xmlrpc.php {
  allowBrowse 0
  accessControl {
    deny ALL
  }
}

Save: Ctrl + X → Y → Enter

Step 3.4: Update Main OpenLiteSpeed Configuration

 sudo nano /usr/local/lsws/conf/httpd_config.conf 

Find the listener Default section (around line 185) and update:

 

listener Default {
address *:80
secure 0
map example.com example.com, www.example.com
} 

Scroll to the bottom and add:

 

virtualhost example.com {
vhRoot /usr/local/lsws/example.com
configFile /usr/local/lsws/conf/vhosts/example.com/vhconf.conf
allowSymbolLink 1
enableScript 1
restrained 1
setUIDMode 2
}

Save: Ctrl + X → Y → Enter

Step 3.5: Restart OpenLiteSpeed

 sudo /usr/local/lsws/bin/lswsctrl restart 

Part 4: Install WordPress

Step 4.1: Secure MySQL

 sudo mysql_secure_installation 

Follow prompts:


Enter current password: Press Enter (empty)
Switch to unix_socket: n
Change root password: Y → Enter strong password
Remove anonymous users: Y
Disallow root remote login: Y
Remove test database: Y
Reload privileges: Y

Step 4.2: Create WordPress Database

 sudo mysql -u root -p 

Enter your root password, then run:

 

CREATE DATABASE wordpress;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Save these credentials – you’ll need them!

Step 4.3: Download WordPress

 
cd /usr/local/lsws/example.com/html 
sudo wget https://wordpress.org/latest.tar.gz 
sudo tar -xzvf latest.tar.gz sudo mv wordpress/* . 
sudo rm -rf wordpress latest.tar.gz 

Step 4.4: Configure WordPress

 
sudo cp wp-config-sample.php wp-config.php 
sudo nano wp-config.php 

Update database settings:

 

define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'StrongPassword123!' ); // Your password from Step 4.2
define( 'DB_HOST', 'localhost' );

Generate security keys at: https://api.wordpress.org/secret-key/1.1/salt/

Copy the generated keys and replace the dummy keys in wp-config.php

Add these security settings before /* That’s all, stop editing! */:

 

define('DISALLOW_FILE_EDIT', true);
define('FORCE_SSL_ADMIN', true);
define('WP_AUTO_UPDATE_CORE', 'minor');
define('WP_POST_REVISIONS', 3);
define('AUTOSAVE_INTERVAL', 300);

Save: Ctrl + X → Y → Enter

Step 4.5: Set Permissions

 
sudo chown -R nobody:nogroup /usr/local/lsws/example.com/html 
sudo chmod -R 755 /usr/local/lsws/example.com/html 
sudo find /usr/local/lsws/example.com/html -type f -exec chmod 644 {} ; 
sudo chmod 600 /usr/local/lsws/example.com/html/wp-config.php 

Step 4.6: Complete WordPress Installation

Visit: http://YOUR-IP

Complete the WordPress installation wizard with site title, username, password, and email.

WordPress is now installed! ✅


Part 5: Setup Free SSL Certificate

Step 5.1: Point Your Domain to EC2

At your domain registrar/DNS provider, add A records:

 
Type: A 
Name: @ 
Value: YOUR-EC2-IP 
TTL: 3600

Type: A 
Name: www 
Value: YOUR-EC2-IP 
TTL: 3600 

Wait 5-10 minutes for DNS propagation

Step 5.2: Install Let’s Encrypt (acme.sh)

 cd ~ curl https://get.acme.sh | sh source ~/.bashrc 

Step 5.3: Request SSL Certificate

#Temporarily change ownership for validation
sudo chown -R ubuntu:ubuntu /usr/local/lsws/example.com/html
#Request certificate
~/.acme.sh/acme.sh --issue -d example.com -d www.example.com -w /usr/local/lsws/example.com/html
#Change ownership back
sudo chown -R nobody:nogroup /usr/local/lsws/example.com/html 

Step 5.4: Install Certificate

#Create SSL directory
sudo mkdir -p /usr/local/lsws/conf/cert/example.com
#Copy certificates
sudo cp ~/.acme.sh/example.com_ecc/fullchain.cer /usr/local/lsws/conf/cert/example.com/fullchain.pem 
sudo cp ~/.acme.sh/example.com_ecc/example.com.key /usr/local/lsws/conf/cert/example.com/key.pem 
sudo cp ~/.acme.sh/example.com_ecc/example.com.cer /usr/local/lsws/conf/cert/example.com/cert.pem
#Set permissions
sudo chmod 600 /usr/local/lsws/conf/cert/example.com/key.pem 
sudo chmod 644 /usr/local/lsws/conf/cert/example.com/*.pem 

Step 5.5: Configure HTTPS Listener

 sudo nano /usr/local/lsws/conf/httpd_config.conf 

Add after the listener Default section:

 

listener SSL {
address *:443
secure 1
keyFile /usr/local/lsws/conf/cert/example.com/key.pem
certFile /usr/local/lsws/conf/cert/example.com/fullchain.pem
certChain 1
sslProtocol 24
map example.com example.com, www.example.com
}

Save: Ctrl + X → Y → Enter

Step 5.6: Update WordPress URLs

 mysql -u wpuser -p wordpress 
 

UPDATE wp_options SET option_value = 'https://example.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://example.com' WHERE option_name = 'home';
EXIT;

Step 5.7: Force HTTPS Redirect

 sudo nano /usr/local/lsws/conf/vhosts/example.com/vhconf.conf 

Update the rewrite section:

 

rewrite {
  enable 1
  autoLoadHtaccess 1
  rules <<<END_rules
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
END_rules
}

Save and restart:

 sudo /usr/local/lsws/bin/lswsctrl restart 

Test: https://example.com – Should show green padlock! 🔒


Part 6: Maximum Security Configuration

Step 6.1: Install UFW Firewall

 
sudo apt install ufw -y
#Default policies
 
sudo ufw default deny incoming 
sudo ufw default allow outgoing
#Allow necessary ports
 
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 7080/tcp # WebAdmin
#Enable firewall
 
sudo ufw enable
#Verify
 
sudo ufw status 

Step 6.2: Install Fail2Ban (Brute Force Protection)

 sudo apt install fail2ban -y 

Create configuration:

 sudo nano /etc/fail2ban/jail.local 

Add:

 

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
destemail = your-email@example.com
action = %(action_mwl)s
[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log
[wordpress-auth]
enabled = true
filter = wordpress-auth
logpath = /usr/local/lsws/example.com/logs/access.log
maxretry = 3
port = http,https

Create WordPress filter:

 sudo nano /etc/fail2ban/filter.d/wordpress-auth.conf 
 

[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
            ^<HOST> .* "POST /xmlrpc.php
ignoreregex =

Start Fail2Ban:

 
sudo systemctl restart fail2ban 
sudo systemctl enable fail2ban 
sudo fail2ban-client status 

Step 6.3: Harden PHP Configuration

 sudo nano /usr/local/lsws/lsphp83/etc/php/8.3/litespeed/php.ini 

Update these settings:

 

expose_php = Off
display_errors = Off
log_errors = On
allow_url_fopen = Off
allow_url_include = Off
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
memory_limit = 256M
disable_functions = passthru,shell_exec,system,proc_open,popen

Save and restart:

 sudo /usr/local/lsws/bin/lswsctrl restart 

Step 6.4: Enable Automatic Security Updates

 
sudo apt install unattended-upgrades -y 
sudo dpkg-reconfigure -plow unattended-upgrades 

Select Yes

6.5: Secure WebAdmin Panel

By default, OpenLiteSpeed WebAdmin is accessible on port 7080 from any IP. For maximum security, restrict it to localhost-only and access via SSH tunnel.

Step 6.5.1: Restrict WebAdmin to Localhost

sudo nano /usr/local/lsws/admin/conf/admin_config.conf

Find the listener section and change:

listener adminListener {
  address                 *:7080

To:

listener adminListener {
  address                 127.0.0.1:7080

Save: Ctrl + X → Y → Enter

Step 6.5.2: Restart OpenLiteSpeed

sudo /usr/local/lsws/bin/lswsctrl restart

### Step 6.5.3: Verify WebAdmin is Localhost-Only

sudo ss -tlnp | grep 7080

Should show: 127.0.0.1:7080 (not *:7080 or 0.0.0.0:7080)

Step 6.5.4: Access WebAdmin via SSH Tunnel

**Mac/Linux:**

Create an alias in ~/.zshrc or ~/.bash_profile:

alias nsadmin="ssh -i /path/to/wordpress-key.pem -L 7080:localhost:7080 ubuntu@YOUR-IP"

Reload configuration:

source ~/.zshrc

**Windows (PowerShell):**

Create a function in your PowerShell profile:

function nsadmin { ssh -i C:\path\to\wordpress-key.pem -L 7080:localhost:7080 ubuntu@YOUR-IP }

Step 6.5.5: Using WebAdmin

**1. Open terminal and connect:**

nsadmin

**2. Keep terminal window open**

**3. Open browser and visit:**

http://localhost:7080

**4. Login with your admin credentials**

**Important:**
– Use http:// not https:// for localhost
– Keep the SSH terminal running while using WebAdmin
– When you close SSH, WebAdmin access stops (by design)

### Security Benefits:

✅ WebAdmin completely invisible from internet
✅ No exposure even if firewall misconfigured
✅ Requires SSH authentication before WebAdmin access
✅ No additional attack surface on port 7080


Part 7: Performance Optimization with Redis

Step 7.1: Install Redis

 
sudo apt install redis-server -y 
sudo systemctl start redis-server 
sudo systemctl enable redis-server 

Step 7.2: Configure Redis

 sudo nano /etc/redis/redis.conf 

Find and update:

 
maxmemory 256mb 
maxmemory-policy allkeys-lru 

Restart:

 sudo systemctl restart redis-server 

Step 7.3: Install LiteSpeed Cache Plugin

Login to WordPress admin: https://example.com/wp-admin

Go to Plugins → Add New
Search “LiteSpeed Cache”
Install → Activate

Step 7.4: Enable Redis Object Cache

LiteSpeed Cache → Cache → Object
Object Cache: Turn ON
Method: Redis
Host: localhost
Port: 6379
Save Changes
Test Connection – Should show “Connected” ✅

Step 7.5: Optimize LiteSpeed Cache Settings

Cache tab:
Cache Mobile: ON
TTL: 604800 (1 week)

Page Optimization:
CSS Minify: ON
CSS Combine: ON
JavaScript Minify: ON
HTML Minify: ON

Image Optimization:
Auto Pull Images: ON
WebP Replacement: ON


Part 8: Email Configuration (Brevo SMTP)

Step 8.1: Create Brevo Account

Sign up at https://www.brevo.com/ (free – 300 emails/day)
Verify your email
Complete account setup

Step 8.2: Get API Key

In Brevo Dashboard:

Settings → SMTP & API
Click “API Keys” tab
Generate a new API key
Name: “WordPress”
Copy the key (starts with xkeysib-…)

Step 8.3: Authenticate Domain

In Brevo:

Settings → Senders & IP
Domains → Add a domain
Enter: example.com
Add DNS records they provide to your domain’s DNS

Typical DNS records:

 
Type: TXT 
Name: @ 
Value: brevo-code=xxxxx

Type: CNAME 
Name: mail._domainkey 
Value: (Brevo provides) 

Update SPF record:

 v=spf1 include:spf.brevo.com ~all 

Step 8.4: Install WP Mail SMTP Plugin

In WordPress:

Plugins → Add New
Search “WP Mail SMTP”
Install → Activate

Step 8.5: Configure WordPress Email

WP Mail SMTP → Settings:

From Email: noreply@example.com (or your email)
From Name: Your Site Name
Mailer: Brevo
API Key: Paste your Brevo API key
Save Settings

Test: WP Mail SMTP → Tools → Send test email

Step 8.6: Configure Server Email (Postfix)

#Install Postfix
sudo apt install postfix mailutils -y 

Select Internet Site and set system mail name to example.com

Configure for Brevo:

 sudo nano /etc/postfix/main.cf 

Add at bottom:

 

relayhost = [smtp-relay.brevo.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_use_tls = yes

Get Brevo SMTP credentials from: Brevo Dashboard → SMTP & API → SMTP tab → Create SMTP key

Create credentials file:

 sudo nano /etc/postfix/sasl_passwd 

Add (replace with your credentials):

 [smtp-relay.brevo.com]:587 your-login@smtp-brevo.com:your-smtp-key 

Apply:

 
sudo chmod 600 /etc/postfix/sasl_passwd 
sudo postmap /etc/postfix/sasl_passwd 
sudo systemctl restart postfix 

Test server email:

 echo "Test from server" | mail -s "Test" your-email@example.com 

Part 9: Final Checks & Testing

Step 9.1: Security Headers Test

 curl -I https://example.com 

Should show:
Strict-Transport-Security
X-Frame-Options
X-Content-Type-Options
X-XSS-Protection

Online test: https://securityheaders.com/?q=example.com

Step 9.2: SSL Test

Visit: https://www.ssllabs.com/ssltest/analyze.html?d=example.com

Target: A or A+ rating

Step 9.3: Performance Test

Visit: https://pagespeed.web.dev/

Enter: example.com

Target: 90+ score

Step 9.4: Email Test

Visit: https://www.mail-tester.com/

Send test email to address shown

Target: 8-10/10 score


Part 10: Maintenance & Backups

Step 10.1: Create Backup Script

 sudo nano /usr/local/bin/backup-wordpress.sh 

Add:

 

#!/bin/bash
BACKUP_DIR="/home/ubuntu/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_USER="wpuser"
DB_PASS="YourPassword"
DB_NAME="wordpress"

mkdir -p $BACKUP_DIR

mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz
tar -czf $BACKUP_DIR/files_$DATE.tar.gz /usr/local/lsws/example.com/html/

find $BACKUP_DIR -type f -mtime +7 -delete

echo "Backup completed: $DATE"

Make executable:

 sudo chmod +x /usr/local/bin/backup-wordpress.sh 

Schedule daily backups:

 crontab -e 

Add:

 

0 2 * * * /usr/local/bin/backup-wordpress.sh >> /home/ubuntu/backup.log 2>&1

Step 10.2: Monitor System Resources

#Check disk space
 
df -h
#Check memory usage
 
free -h
#Check OpenLiteSpeed status
 
sudo systemctl status lsws
#Check Redis status
 
sudo systemctl status redis-server
#Check fail2ban status
 
sudo fail2ban-client status 

Part 11: Add Swap

  • t3.micro has only 1GB RAM – can run out during WordPress updates, plugin installations, or backups
  • Running multiple services – OpenLiteSpeed + MariaDB + Redis + PHP can consume memory quickly
  • Prevents OOM crashes – swap acts as overflow when RAM fills up
  • AWS best practice – recommended for small instances

Recommended Swap Size:
For 1GB RAM → 2GB swap (2x RAM is standard)


# Check if swap exists
sudo swapon --show
free -h

# Create 2GB swap file
sudo fallocate -l 2G /swapfile

# Set correct permissions
sudo chmod 600 /swapfile

# Make it a swap file
sudo mkswap /swapfile

# Enable swap
sudo swapon /swapfile

# Verify
free -h

# Make permanent (survives reboots)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Optimize swappiness (lower = use RAM more, swap less)
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf


Useful Commands Reference

Restart OpenLiteSpeed:

 sudo /usr/local/lsws/bin/lswsctrl restart 

Check OpenLiteSpeed logs:

 sudo tail -f /usr/local/lsws/example.com/logs/error.log 

Restart Redis:

 sudo systemctl restart redis-server 

Check Redis connection:

 
redis-cli ping 
# Should return 
PONG 

View mail logs:

 sudo tail -f /var/log/mail.log 

Renew SSL certificate:

 ~/.acme.sh/acme.sh --renew -d example.com 

WebAdmin access: https://YOUR-IP:7080


Troubleshooting

Issue: Site shows 404 error

Solution: #Check virtual host mapping

sudo nano /usr/local/lsws/conf/httpd_config.conf
#Verify "map example.com" line exists in listeners
sudo /usr/local/lsws/bin/lswsctrl restart 

Issue: SSL certificate error

Solution: #Verify certificate files exist

sudo ls -la /usr/local/lsws/conf/cert/example.com/
#Check permissions
sudo chmod 600 /usr/local/lsws/conf/cert/example.com/key.pem 
sudo chmod 644 /usr/local/lsws/conf/cert/example.com/fullchain.pem 

Issue: WordPress emails not sending

Solution:

#Check Postfix status
sudo systemctl status postfix
#Check mail logs
sudo tail -50 /var/log/mail.log
#Test SMTP connection
telnet smtp-relay.brevo.com 587 

Issue: Redis not connecting

Solution: #Restart Redis

sudo systemctl restart redis-server
#Check Redis status
redis-cli ping
#Restart OpenLiteSpeed
sudo /usr/local/lsws/bin/lswsctrl restart 

Cost Breakdown

First 6 Months (Free Tier):

EC2 t3.micro: £0/month
30GB EBS storage: £0/month
Data transfer: £0/month (15GB free)
SSL certificate: £0/month (Let’s Encrypt)
Email (Brevo): £0/month (300 emails/day)

Total: £0/month

After Free Tier (Month 6):

EC2 t3.micro: ~£8.50/month
30GB EBS storage: ~£3/month
Data transfer: Variable
Email (Brevo): £0/month (still free)

Estimated Total: ~£12-15/month


Performance Benchmarks

What to expect:

Page load time: 0.5-1.5 seconds
Time to first byte (TTFB): 100-300ms
PageSpeed score: 90-100
Security headers grade: A+
SSL rating: A or A+
Concurrent users supported: 50-100 (t2.micro)


Next Steps & Improvements

Recommended Enhancements:

CDN: Add Cloudflare for global content delivery
Monitoring: Setup uptime monitoring (UptimeRobot, Pingdom)
Backup offsite: Sync backups to S3 or external storage
Scaling: Upgrade to t2.small or t3.small for high traffic
Database: Move to RDS for better reliability (larger sites)

Security Enhancements:

Install WordFence: Advanced firewall and malware scanning
Two-factor auth: Enable 2FA for WordPress admin
SSH key only: Disable password authentication
Restrict WebAdmin: Firewall WebAdmin port to specific IPs
Regular audits: Monthly security reviews


Conclusion

You now have a production-ready WordPress site running on AWS EC2 with:

✅ Performance: OpenLiteSpeed + Redis = lightning fast
✅ Security: A+ rating with enterprise-level protection
✅ Reliability: Free tier eligible for 12 months
✅ Email: Fully functional SMTP (300/day free)
✅ SSL: Free HTTPS with auto-renewal
✅ Modern: HTTP/2, HTTP/3, latest PHP 8.3

Total setup cost: £0/month (first 6 month ec2 Amazon)
Performance vs shared hosting: 3-5x faster
Security vs typical WordPress: Significantly hardened

This setup rivals premium managed WordPress hosting costing £50-100/month!


Support & Resources

Official Documentation:

OpenLiteSpeed: https://docs.litespeedtech.com/
AWS EC2: https://docs.aws.amazon.com/ec2/
WordPress: https://wordpress.org/documentation/
LiteSpeed Cache: https://docs.litespeedtech.com/lscache/

Community:

OpenLiteSpeed Forum: https://forum.openlitespeed.org/
WordPress Support: https://wordpress.org/support/
AWS Community: https://repost.aws/


About This Guide

Last Updated: April 30, 2026
Tested On: Ubuntu 24.04 LTS, PHP 8.3, OpenLiteSpeed 1.7+
Author: Nuno / nuno-sarmento.com

Questions or issues? Leave a comment below or contact me at hello@nuno-sarmento.com


Did this guide help you? Share it with others who might benefit!

ABOUT AUTHOR

Nuno

Hi, I'm a Freelance Web Developer and WordPress Expert based in London with a wealth of website development and support experience. I am great at problem solving and developing quick solutions.