Skip to main content

Automation & Bash Scripts

Production-ready scripts and patterns. Drop them into /usr/local/lsws/scripts/ and schedule with cron.

Script Directory
sudo mkdir -p /usr/local/lsws/scripts
sudo chmod 700 /usr/local/lsws/scripts

Health Monitor

/usr/local/lsws/scripts/ols-health.sh
#!/bin/bash
# Full OLS health check — run manually or from cron
OLS_ROOT="/usr/local/lsws"
PID_FILE="/tmp/lshttpd/lshttpd.pid"
G='\033[0;32m'; R='\033[0;31m'; NC='\033[0m'
status() { systemctl is-active --quiet lsws && echo -e "${G}ACTIVE${NC}" || echo -e "${R}DOWN${NC}"; }

echo "============= OLS Health $(date '+%F %T') ============="
printf "%-24s %s\n" "Service:" "$(status)"
printf "%-24s %s\n" "Version:" "$($OLS_ROOT/bin/lshttpd -v 2>&1 | head -1)"
printf "%-24s %s\n" "PID:" "$(cat $PID_FILE 2>/dev/null || echo N/A)"
printf "%-24s %s\n" "lshttpd workers:" "$(ps aux | grep lshttpd | grep -v grep | wc -l)"
printf "%-24s %s\n" "lsphp workers:" "$(ps aux | grep lsphp | grep -v grep | wc -l)"
printf "%-24s %s\n" "Ports listening:" "$(sudo ss -tlnp | grep lshttpd | awk '{print $4}' | tr '\n' ' ')"
printf "%-24s %s\n" "Uptime:" "$(ps -p $(cat $PID_FILE 2>/dev/null) -o etime= 2>/dev/null | tr -d ' ' || echo N/A)"
echo ""
echo "--- Last 5 error lines ---"
sudo tail -5 "$OLS_ROOT/logs/error.log"
echo "======================================================="

Auto-Restart with Alerting

/usr/local/lsws/scripts/ols-watchdog.sh
#!/bin/bash
# Monitor OLS and restart + alert if down
# Cron: */2 * * * * sudo bash /usr/local/lsws/scripts/ols-watchdog.sh

WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
LOG="/var/log/ols-watchdog.log"

if ! systemctl is-active --quiet lsws; then
systemctl restart lsws
sleep 3

if systemctl is-active --quiet lsws; then
MSG="⚠️ OLS was DOWN — restarted successfully on $(hostname) at $(date)"
else
MSG="🚨 OLS is DOWN and FAILED to restart on $(hostname) at $(date)"
fi

echo "$MSG" >> "$LOG"

# Slack webhook alert
curl -s -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MSG\"}" "$WEBHOOK_URL" > /dev/null
fi

Config Backup

/usr/local/lsws/scripts/ols-backup.sh
#!/bin/bash
# Backup OLS config + SSL — run before upgrades
BACKUP_DIR="${1:-/root/ols-backups}"
DATE=$(date +%Y%m%d-%H%M%S)
ARCHIVE="$BACKUP_DIR/ols-$DATE.tar.gz"
mkdir -p "$BACKUP_DIR"

PATHS=(
"/usr/local/lsws/conf"
"/usr/local/lsws/admin/conf"
"/etc/ssl/private"
"/etc/ssl/certs"
)

tar -czf "$ARCHIVE" "${PATHS[@]}" 2>/dev/null && \
echo "[✓] Backup: $ARCHIVE ($(du -sh "$ARCHIVE" | awk '{print $1}'))" || \
{ echo "[✗] Backup failed"; exit 1; }

# Keep only last 10 backups
ls -t "$BACKUP_DIR"/ols-*.tar.gz 2>/dev/null | tail -n +11 | xargs rm -f

Safe Graceful Reload

/usr/local/lsws/scripts/ols-reload.sh
#!/bin/bash
# Graceful reload with post-check
LOG="/usr/local/lsws/logs/error.log"
BEFORE=$(wc -l < "$LOG")

echo "[+] Graceful reload..."
sudo /usr/local/lsws/bin/lswsctrl restart
sleep 2

NEW=$(( $(wc -l < "$LOG") - BEFORE ))
[ $NEW -gt 0 ] && { echo "[!] $NEW new log entries:"; tail -n $NEW "$LOG"; } || echo "[✓] No new errors"
systemctl is-active --quiet lsws && echo "[✓] Service active." || { echo "[✗] Service DOWN!"; exit 1; }

New Vhost Provisioner

/usr/local/lsws/scripts/new-vhost.sh
#!/bin/bash
# Create a new OLS vhost from CLI
# Usage: sudo bash new-vhost.sh example.com [php84|php83]

DOMAIN="${1:?Usage: $0 <domain> [lsphp_version]}"
PHP_VERSION="${2:-lsphp84}"
WEB_ROOT="/var/www/$DOMAIN/public"
VH_DIR="/usr/local/lsws/conf/vhosts/$DOMAIN"

mkdir -p "$WEB_ROOT" "$VH_DIR"
chown -R nobody:nogroup "/var/www/$DOMAIN"
chmod -R 755 "/var/www/$DOMAIN"

echo "<h1>$DOMAIN — OpenLiteSpeed</h1>" > "$WEB_ROOT/index.html"

cat > "$VH_DIR/vhconf.conf" <<CONF
docRoot $WEB_ROOT
vhDomain $DOMAIN, www.$DOMAIN
enableGzip 1
enableBr 1

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

scripthandler {
add lsapi:$PHP_VERSION php
}

accessControl {
allow *
}

rewrite {
enable 1
autoLoadHtaccess 1
}
CONF

echo "[✓] vhconf: $VH_DIR/vhconf.conf"
echo "[✓] Web root: $WEB_ROOT"
echo ""
echo "[!] Manual step: add virtualhost block to httpd_config.conf"
echo "[!] Then run: sudo /usr/local/lsws/bin/lswsctrl restart"

SSL Certificate Check + Alert

/usr/local/lsws/scripts/ssl-check.sh
#!/bin/bash
# Check SSL cert expiry for all domains — alert if < 14 days
# Usage: bash ssl-check.sh example.com other.com

WARN_DAYS=14
ALERT_CMD="echo" # replace with mail/slack/webhook as needed

for DOMAIN in "$@"; do
EXPIRY=$(echo | openssl s_client -connect "$DOMAIN:443" -servername "$DOMAIN" 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

if [ -z "$EXPIRY" ]; then
$ALERT_CMD "SSL CHECK FAIL: Cannot reach $DOMAIN:443"
continue
fi

EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -jf "%b %d %T %Y %Z" "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -lt $WARN_DAYS ]; then
$ALERT_CMD "SSL EXPIRY WARNING: $DOMAIN expires in $DAYS_LEFT days ($EXPIRY)"
else
echo "[✓] $DOMAIN$DAYS_LEFT days remaining"
fi
done

Log Analysis One-Liners

# Top 10 requested URLs
sudo awk '{print $7}' /usr/local/lsws/logs/access.log | sort | uniq -c | sort -rn | head -10

# Top 10 IPs by request count
sudo awk '{print $1}' /usr/local/lsws/logs/access.log | sort | uniq -c | sort -rn | head -10

# All 5xx errors in last hour
sudo awk -v d="$(date -d '1 hour ago' '+%d/%b/%Y:%H')" '$0 ~ d && $9 ~ /^5/' \
/usr/local/lsws/logs/access.log | wc -l

# Unique error types from error.log
sudo grep -oP '\[\K[^\]]+' /usr/local/lsws/logs/error.log | sort | uniq -c | sort -rn

# Bandwidth usage (bytes transferred today)
sudo awk '{sum += $10} END {printf "%.2f GB\n", sum/1024/1024/1024}' \
/usr/local/lsws/logs/access.log

Cron Setup Reference

sudo crontab -e

# Auto-restart if down (every 2 min)
*/2 * * * * sudo bash /usr/local/lsws/scripts/ols-watchdog.sh

# Daily config backup at 2 AM
0 2 * * * sudo bash /usr/local/lsws/scripts/ols-backup.sh /root/ols-backups >> /var/log/ols-backup.log 2>&1

# Weekly SSL cert check
0 8 * * 1 bash /usr/local/lsws/scripts/ssl-check.sh example.com other.com >> /var/log/ssl-check.log 2>&1

# Log rotation at midnight
0 0 * * * sudo find /usr/local/lsws/logs -name "*.log" -size +100M \
-exec gzip -9 {} \; >> /var/log/ols-logrotate.log 2>&1

opencode AI Workflows

Use opencode at the server CLI to get AI assistance directly in your terminal.

# --- ANALYZE ERRORS ---
sudo tail -200 /usr/local/lsws/logs/error.log | \
opencode "analyze these OpenLiteSpeed error logs. group errors by type, identify root causes, and give specific fixes"

# --- GENERATE VHOST CONFIG ---
opencode "write a complete OpenLiteSpeed vhconf.conf for a WordPress site at /var/www/site.com/public, using lsphp84, with HTTPS redirect, cache headers, and security rules"

# --- REVIEW CONFIG FOR SECURITY ---
sudo cat /usr/local/lsws/conf/httpd_config.conf | \
opencode "review this OLS server config for security weaknesses and suggest hardening improvements"

# --- PHP TUNING ADVICE ---
echo "Server RAM: $(free -m | awk 'NR==2{print $2}')MB, PHP workers: $(ps aux | grep lsphp | grep -v grep | wc -l)" | \
opencode "suggest optimal PHP_LSAPI_CHILDREN, maxConns, memory_limit, and OPcache settings for this server"

# --- DIAGNOSE SLOW SITE ---
(
echo "=== OLS Status ==="
systemctl status lsws --no-pager
echo "=== Last 50 errors ==="
sudo tail -50 /usr/local/lsws/logs/error.log
echo "=== Memory ==="
free -m
echo "=== Load ==="
uptime
) | opencode "my WordPress site is slow. analyze this server data and suggest the most impactful fixes"

# --- WRITE AUTOMATION SCRIPT ---
opencode "write a bash script that: checks OLS is running every 5 minutes, restarts it if down, sends a curl POST to a webhook with the server hostname and timestamp, and logs all actions to /var/log/ols-monitor.log"

# --- GENERATE .HTACCESS ---
opencode "write an optimized .htaccess for a WordPress site on OpenLiteSpeed with: HTTPS redirect, browser caching for static assets, blocked access to sensitive files, and compression hints"
tmux + opencode Workflow
┌─────────────────────────┬─────────────────────┐
│ │ │
│ vim vhconf.conf │ opencode session │
│ (editing) │ (AI assistance) │
│ │ │
├─────────────────────────┴─────────────────────┤
│ tail -f /usr/local/lsws/logs/error.log │
│ (live monitoring) │
└────────────────────────────────────────────────┘

Three panes: edit → AI review → live log tail. Apply changes, check the log pane instantly.


Useful Aliases (add to ~/.bashrc)

# OpenLiteSpeed aliases
alias olsrestart='sudo /usr/local/lsws/bin/lswsctrl restart'
alias olsstatus='sudo systemctl status lsws'
alias olslog='sudo tail -f /usr/local/lsws/logs/error.log'
alias olsversion='/usr/local/lsws/bin/lshttpd -v'
alias olsworkers='ps aux | grep lshttpd | grep -v grep | wc -l'
alias php84='/usr/local/lsws/lsphp84/bin/lsphp'
alias phpworkers='ps aux | grep lsphp | grep -v grep | wc -l'
alias olshealth='sudo bash /usr/local/lsws/scripts/ols-health.sh'

# Reload aliases
source ~/.bashrc