Skip to main content

Script Automation

Shell scripts eliminate repetitive OLS tasks and make your operations repeatable and auditable. Every script here can be run from tmux, scheduled with cron, or invoked by opencode.

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

Health Check Script

/usr/local/lsws/scripts/ols-health.sh
#!/bin/bash
# OpenLiteSpeed Health Check — run with: sudo bash ols-health.sh

OLS_ROOT="/usr/local/lsws"
LOG_FILE="$OLS_ROOT/logs/error.log"
PID_FILE="/tmp/lshttpd/lshttpd.pid"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
GREEN='\033[0;32m'; RED='\033[0;31m'; NC='\033[0m'

svc_status() { systemctl is-active --quiet lsws && echo -e "${GREEN}ACTIVE${NC}" || echo -e "${RED}DOWN${NC}"; }

echo "================================================="
echo " OpenLiteSpeed Health — $TIMESTAMP"
echo "================================================="
printf "%-22s %s\n" "Service:" "$(svc_status)"
printf "%-22s %s\n" "Version:" "$($OLS_ROOT/bin/lshttpd -v 2>&1 | head -1)"
printf "%-22s %s\n" "PID:" "$(cat $PID_FILE 2>/dev/null || echo 'not found')"
printf "%-22s %s\n" "lshttpd workers:" "$(ps aux | grep lshttpd | grep -v grep | wc -l)"
printf "%-22s %s\n" "lsphp workers:" "$(ps aux | grep lsphp | grep -v grep | wc -l)"
printf "%-22s %s\n" "Listening:" "$(sudo ss -tlnp | grep lshttpd | awk '{print $4}' | tr '\n' ' ')"
printf "%-22s %s\n" "Uptime:" "$(ps -p $(cat $PID_FILE 2>/dev/null) -o etime= 2>/dev/null | tr -d ' ' || echo 'N/A')"
echo ""
echo "Last error: $(sudo tail -1 $LOG_FILE 2>/dev/null)"
echo "----- Recent errors (last 5) -----"
sudo tail -5 "$LOG_FILE"
echo "================================================="

New Virtual Host Provisioner

/usr/local/lsws/scripts/new-vhost.sh
#!/bin/bash
# Provision a new OLS virtual host with dirs, permissions, and config
# Usage: sudo bash new-vhost.sh example.com

DOMAIN="${1:?Usage: $0 <domain>}"
WEB_ROOT="/var/www/$DOMAIN/public"
OLS_CONF_DIR="/usr/local/lsws/conf/vhosts/$DOMAIN"

echo "[+] Provisioning: $DOMAIN"

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

# Default index page
cat > "$WEB_ROOT/index.html" <<HTML
<!DOCTYPE html><html><body><h1>$DOMAIN on OpenLiteSpeed</h1></body></html>
HTML

# Write vhconf.conf
cat > "$OLS_CONF_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:lsphp84 php
}

accessControl {
allow *
}

rewrite {
enable 1
autoLoadHtaccess 1
}
CONF

echo "[✓] Config: $OLS_CONF_DIR/vhconf.conf"
echo "[✓] Web root: $WEB_ROOT"
echo ""
echo "[!] Next: Register vhost in httpd_config.conf, then run:"
echo " sudo /usr/local/lsws/bin/lswsctrl restart"

Configuration Backup Script

/usr/local/lsws/scripts/ols-backup.sh
#!/bin/bash
# Backup OLS config and SSL — run before upgrades or major changes
# Usage: sudo bash ols-backup.sh [backup-dir]

BACKUP_BASE="${1:-/root/ols-backups}"
DATE=$(date +%Y%m%d-%H%M%S)
ARCHIVE="$BACKUP_BASE/ols-config-$DATE.tar.gz"
mkdir -p "$BACKUP_BASE"

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 last 10 backups
ls -t "$BACKUP_BASE"/ols-config-*.tar.gz 2>/dev/null | tail -n +11 | xargs rm -f
echo "[✓] Pruned old backups. Current count: $(ls $BACKUP_BASE/*.tar.gz 2>/dev/null | wc -l)"

Safe Reload Script

Applies a graceful reload and immediately checks the error log for new failures.

/usr/local/lsws/scripts/ols-reload.sh
#!/bin/bash
# Safe 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

AFTER=$(wc -l < "$LOG")
NEW=$((AFTER - BEFORE))

if [ $NEW -gt 0 ]; then
echo "[!] $NEW new log lines after reload:"
tail -n "$NEW" "$LOG"
else
echo "[✓] Reload complete. No new errors."
fi

systemctl is-active --quiet lsws && echo "[✓] Service active." || echo "[✗] Service DOWN!"

Cron Setup

# Edit root crontab
sudo crontab -e

# Auto-restart if OLS goes down (every 5 min)
*/5 * * * * systemctl is-active lsws || (systemctl restart lsws && echo "restarted $(date)" >> /var/log/ols-restart.log)

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

opencode AI Automation

# Analyze error logs for root causes
sudo tail -200 /usr/local/lsws/logs/error.log | \
opencode "analyze these OLS errors, group by type, and suggest fixes"

# Generate a vhost config for WordPress
opencode "write an OLS vhconf.conf for WordPress at /var/www/site.com/public using lsphp84 with cache headers and rewrite rules"

# Security review of server config
sudo cat /usr/local/lsws/conf/httpd_config.conf | \
opencode "review this OLS config for security misconfigurations and hardening opportunities"

# Generate a monitoring script
opencode "write a bash script monitoring OpenLiteSpeed, sending a webhook alert on failure, and logging recovery"
opencode + tmux

Split your tmux session: config editing in one pane, opencode dialogue in another, and error log tail in a third. This is the fastest way to iterate on OLS config changes.


What's Next