Tag: DevOps

Preventing Unnecessary OpenLiteSpeed Reloads from .htaccess Touches

Preventing Unnecessary Open Lite Speed Reloads
  • Introduction

    In OpenLiteSpeed 1.8.x, the server does not automatically reload when .htaccess or configuration files change. For WordPress and PHP hosting environments, this means that changes to rewrite rules or caching directives in .htaccess files will not take effect until the server is manually reloaded or restarted.

    System administrators running multi-site setups, therefore, often add automation to detect when .htaccess files have changed and trigger a graceful reload. The challenge is that the usual methods can reload unnecessarily when a file’s timestamp changes but its content doesn’t; for example, during deployments, syncs, or backup restores. My improved script solves this problem.

    The Traditional Example from OpenLiteSpeed Forums

    A commonly suggested script looks a bit like this:

    #!/bin/bash
    #
    # If any .htaccess files change, reload the lsws server and show which ones changed
    #

    # Find .htaccess files newer than the lsws cgid binary
    changed_files=$(find /var/www/*/htdocs/ -maxdepth 2 -type f -name '.htaccess' -newer /usr/local/lsws/cgid)

    if [[ -n "$changed_files" ]]; then
        echo "The following .htaccess file(s) changed:"
        echo "$changed_files"
        /usr/bin/systemctl reload lsws
        echo "Reloaded lsws due to changes in .htaccess file(s)"
    fi

    This approach compares modification times (-newer /usr/local/lsws/cgid), so if a deployment tool or the site touches files without altering them, the script will reload OpenLiteSpeed needlessly.

    The Tekate Improvement for OpenLiteSpeed reload on .htaccess change

    To eliminate false reloads, Tekate’s version uses SHA-256 content hashing rather than timestamps. The server reloads only when an .htaccess file’s contents actually change.

    Key advantages:

    • Detects real content changes only
    • Avoids redundant reloads from file syncs or touches etc
    • Prevents overlapping cron runs with flock
    • Runs lightly under nice and ionice
    • Uses the standard /var/www/*/htdocs/ structure
    • Compatible with OpenLiteSpeed 1.8.x on Oracle Linux 9

    Here’s the improved script:

    #!/bin/bash
    # Reload OpenLiteSpeed only when .htaccess content actually changes.
    # Tested on OpenLiteSpeed 1.8.x (Oracle Linux 8).
    # Uses standard web root location /var/www/ for all sites.
    # Simple reporting: show only ADDED/MODIFIED entries (hash + path).

    set -euo pipefail

    # Prevent overlapping cron runs
    exec 9>/run/lock/htaccess-watch.lock || exit 0
    if ! flock -w 2 9; then
      logger -t htaccess-watch "Skipped: previous run still holding lock"
      exit 0
    fi

    HASH_FILE="/root/.htaccess_hashes"
    TMP_HASH="$(mktemp /tmp/.htaccess_hashes.XXXXXX)"
    trap 'rm -f "$TMP_HASH"' EXIT

    # Build new list of hashes; deterministic ordering
    LC_ALL=C nice -n 10 ionice -c3 \
      find /var/www/*/htdocs/ -maxdepth 2 -type f -name '.htaccess' -exec sha256sum {} \; 2>/dev/null \
      | LC_ALL=C sort > "$TMP_HASH"

    # First run: seed baseline and exit quietly
    if [[ ! -f "$HASH_FILE" ]]; then
      mv -f "$TMP_HASH" "$HASH_FILE"
      exit 0
    fi

    # If lists differ, reload and print out for email only new/modified lines
    if ! diff -q "$HASH_FILE" "$TMP_HASH" >/dev/null; then
      echo "The following .htaccess file(s) changed (added/modified):"
      if comm -13 "$HASH_FILE" "$TMP_HASH" | grep -q .; then
        comm -13 "$HASH_FILE" "$TMP_HASH"
      else
        echo "(no added/modified entries — change was deletions only)"
      fi

      /usr/bin/systemctl reload lsws
      echo "Reloaded lsws due to actual content changes in .htaccess file(s)"
      logger -t htaccess-watch "Reloaded lsws due to .htaccess content changes"

      mv -f "$TMP_HASH" "$HASH_FILE"
    fi

    Setting Up the Cron Job

    Add this to the root crontab to check for .htaccess changes every three minutes and email the admin only when reloads occur:

    */3 * * * * /root/scripts/serverReloadLsws | /usr/local/bin/maybe_mail "server: openlitespeed reloaded" webmaster@example.com

    In this cron entry, the maybe_mail script only emails to the specified email address if it is passed content through stdin.

    This ensures:
    – OpenLiteSpeed reloads automatically on real .htaccess content changes
    – SysAdmins get concise, actionable notifications
    – No redundant reloads or “spammy” alerts from unmodified files

    Why Tekate’s Version Is Preferable

    FeatureOld ExampleTekate Script
    Relies on file timestampsYesNo
    Detects real content changesNoYes
    Prevents overlapping runsNoYes
    Lightweight and deterministicBasicOptimised

    Conclusion

    OpenLiteSpeed 1.8.x doesn’t auto-reload when .htaccess changes. By introducing a hash-based check, my script keeps sites perfectly in sync with their configuration while minimising unnecessary reloads. It’s a small but elegant improvement that reinforces our philosophy of performance through precision, essential for modern high-performance WordPress environments.

    Now, I shouldn’t have to tell you this 🙂 This script is provided as “as-is.” Use it at your own risk. Test thoroughly in a staging environment before production deployment. It was tested on OpenLiteSpeed 1.8.x using systemd on Oracle Linux 9 (RHEL-based), modifications may be needed for other environments.