cPanel 7d ago 11 views 5 min read

Why I stopped cPanel auto-updates and schedule WHM upgrades manually

I've run dedicated servers for over a decade. I've seen every flavor of Linux, every version of cPanel, and the pain of a surprise upgrade at 3am.

Roy S
Updated 8h ago
Sponsored

Cloud Hosting — blazing fast websites

Fully managed cloud hosting with free SSL, auto-backups and a friendly cPanel. Built for WordPress, Laravel and custom PHP apps.

Why I killed the auto-update daemon

I've run dedicated servers for over a decade. I've seen every flavor of Linux, every version of cPanel, and the pain of a surprise upgrade at 3am.

By default, cPanel installs /usr/local/cpanel/scripts/update --auto and runs it via whostart or a systemd timer. That sounds nice until it touches /usr/local/lib64/php, /usr/local/cpanel/3rdparty, or the Apache module stack.

One night, a cPanel auto-update bumped PHP from 8.2 to 8.3 without my consent. Two sites went down because a popular plugin wasn't compatible. The auto-updater didn't ask for a dry run. It didn't take a snapshot. It just changed things.

I switched to a manual schedule. I now run WHM upgrades on a Tuesday night window, after backups finish. No surprises.

Find and disable the auto-update timer

On Ubuntu 24.04 or AlmaLinux 9, cPanel installs a systemd timer under /etc/systemd/system/cpanel-updates.timer. Check it first:

systemctl list-timers | grep cpanel

You'll see something like:

Mon Jan 13 00:00:00 2025
Mon Jan 13 00:00:00 2025
...
cpanel-updates.timer (Sat Jun 21 00:00:00 2025)

If the timer exists, disable and stop it:

systemctl disable cpanel-updates.timer
systemctl stop cpanel-updates.timer
rm -f /etc/systemd/system/cpanel-updates.timer

Some versions also use a cron file. Check /var/spool/cron/root and /etc/cron.d:

ls -la /var/spool/cron/root
cat /var/spool/cron/root

If you find a line like /usr/local/cpanel/scripts/update --auto > /dev/null 2>&1, remove it or comment it out. I usually comment it so I can re-enable it later if needed:

echo '# /usr/local/cpanel/scripts/update --auto > /dev/null 2>&1' >> /var/spool/cron/root

Confirm the daemon is gone

Run this to be sure nothing is triggering updates in the background:

ps aux | grep -E 'update.*auto|cpanel.*update'

You should see only the cPanel updater process if you run it manually. If you see a daemon named cpanel-update-daemon or similar, kill it:

killall cpanel-update-daemon

Also check the cPanel status page for any scheduled tasks:

/usr/local/cpanel/scripts/uploaddir --list

That last one is a bit obscure, but sometimes cPanel stores scheduled tasks in the upload directory. If you see anything suspicious, delete it.

Set up a safe upgrade schedule

I prefer a weekly window on Tuesday night. Here's how to create a cron job that runs WHM upgrades with a pre-check and a post-check.

First, create a script at /usr/local/bin/whm-upgrade-safe.sh:

#!/bin/bash
set -euo pipefail

BACKUP_DIR="/backup/cpanel/last-upgrade"
LOG="/var/log/cpanel-upgrade.log"
DATE=$(date +%Y%m%d)

# Ensure backup directory exists
mkdir -p "$BACKUP_DIR"

# Pre-check: ensure no critical services are running
if systemctl is-active --quiet nginx; then
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: nginx is active. Skipping upgrade." >> "$LOG"
  exit 0
fi

if systemctl is-active --quiet httpd; then
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: httpd is active. Skipping upgrade." >> "$LOG"
  exit 0
fi

# Optional: take a snapshot before upgrade
# /usr/local/cpanel/scripts/snapshot --full --backup-dir="$BACKUP_DIR" --date="$DATE"

# Run the upgrade
/usr/local/cpanel/scripts/update --rebuild

# Post-check: verify services
if systemctl is-active --quiet nginx; then
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] OK: nginx is active after upgrade." >> "$LOG"
else
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: nginx is inactive after upgrade." >> "$LOG"
fi

if systemctl is-active --quiet httpd; then
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] OK: httpd is active after upgrade." >> "$LOG"
else
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: httpd is inactive after upgrade." >> "$LOG"
fi

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Upgrade completed or skipped." >> "$LOG"

Make it executable:

chmod +x /usr/local/bin/whm-upgrade-safe.sh

Now create a cron entry to run it every Tuesday at 03:00:

0 3 * * 2 /usr/local/bin/whm-upgrade-safe.sh

Add that line to /etc/cron.d/cpanel-weekly-upgrade or to /var/spool/cron/root. I prefer /etc/cron.d because it's easier to manage for multiple servers.

Test the script manually first

Before you let cron run it, test the script manually. Run it with -x to see debug output:

/usr/local/bin/whm-upgrade-safe.sh -x

Watch the log file:

tail -f /var/log/cpanel-upgrade.log

If the script exits with an error, check the cPanel error logs:

tail -100 /var/cpanel/errorlog

Also check journalctl for systemd messages:

journalctl -u cpanel-updates.timer -n 50

If you see an error about PHP version mismatch or a missing module, fix it before scheduling the upgrade.

Keep a rolling backup of the upgrade script

I store one copy of the upgrade script in a git repo. That way, if I change the logic, I can push a new version to all servers with a single commit.

Example git push:

git add /usr/local/bin/whm-upgrade-safe.sh
git commit -m "Update upgrade script for PHP 8.3 compatibility"
git push origin main

Then pull on all servers:

git pull origin main

This keeps your upgrade logic consistent across your fleet.

Monitor upgrade success/failure

After the cron job runs, check the log file:

cat /var/log/cpanel-upgrade.log

If you see "ERROR" entries, investigate immediately. You can also set up a simple alert using a monitoring tool like Nagios, Zabbix, or Prometheus. For example, alert if the log contains "ERROR" within the last hour.

One trick: parse the log with grep and send a Slack message if an error occurs:

grep -i 'ERROR' /var/log/cpanel-upgrade.log | while read line; do
  curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"cPanel upgrade error: $line\"}" $SLACK_WEBHOOK
done

Replace $SLACK_WEBHOOK with your actual webhook URL.

Final checklist before you disable auto-updates

  • Disable the systemd timer and any cron jobs that run auto-updates.
  • Remove or comment out any lines in /etc/cron.d or /var/spool/cron that call /usr/local/cpanel/scripts/update --auto.
  • Create a manual upgrade script that checks services before and after the upgrade.
  • Schedule the script via cron for a low-traffic window (Tuesday 03:00).
  • Test the script manually once before enabling it.
  • Monitor the log file for errors after each run.
  • Keep the upgrade script under version control.

By following these steps, you regain full control over when your cPanel/WHM stack is upgraded. No more midnight surprises, no more broken PHP versions, and no more lost sites.

Sponsored

Windows Dedicated Server

High-performance Windows dedicated servers with licensed Windows Server, Remote Desktop access and enterprise-grade hardware.

Tags: cPanelWHMautomationsafety
0
Was this helpful?

Related tutorials

Comments 0

Login to leave a comment.

No comments yet — be the first to share your thoughts.