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