DEV Community

Cover image for I got tired of manual WordPress maintenance across 8 client sites - so I automated all of it
devautomation
devautomation

Posted on

I got tired of manual WordPress maintenance across 8 client sites - so I automated all of it

If you manage WordPress sites for clients, you know the drill.

Every month, you log into each site, click "Update All Plugins," wait, check if anything broke, run a backup, scan for issues, repeat. For one site it's fine. For eight sites it's 6 hours of your life gone - every single month.

I finally got annoyed enough to fix this properly.

What manual WordPress maintenance actually costs

Here's the math I was doing before I automated:

  • 8 client sites
  • ~45 minutes per site (login, updates, backup verification, security check, client email)
  • = 6 hours/month
  • At $65/hour = $390/month of non-billable time

That's $4,680/year. For clicking update buttons.

The automation stack

I settled on two tools: WP-CLI (runs WordPress commands from the terminal) and SSH (connects to client servers remotely). Both are free, both are standard.

The workflow per site:

  1. SSH into client server
  2. Database backup (before touching anything)
  3. wp core update
  4. wp plugin update --all
  5. wp theme update --all
  6. Security audit
  7. Generate HTML report

Here's a simplified version of the core script:

`ash

!/bin/bash

WP_PATH="/var/www/html/client-site"
BACKUP_DIR="/backups"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M")

1. Backup first

mkdir -p ""
wp --path="" --allow-root db export \
"/db_backup_.sql"

2. Update everything

wp --path="" --allow-root core update
wp --path="" --allow-root plugin update --all
wp --path="" --allow-root theme update --all

3. Flush cache

wp --path="" --allow-root cache flush
`

Simple. But the real value is running this across all client sites from a single config file.

The config approach

I keep a clients.json file:

json
{
"clients": [
{
"name": "Client A Ltd",
"slug": "client_a",
"ssh_host": "server.clienta.com",
"ssh_user": "root",
"ssh_key": "~/.ssh/id_rsa_clienta",
"wp_path": "/var/www/html/clienta",
"active": true
}
]
}

One command runs maintenance across every active client. Add a new client - edit one JSON file.

The security audit

After updates, the script checks:

`ash

Check for exposed debug.log

if [ -f "/wp-content/debug.log" ]; then
echo "WARNING: debug.log exists - may contain sensitive data"
fi

Check wp-config.php permissions

CONFIG_PERMS=$(stat -c "%a" "/wp-config.php")
if [[ ! "" =~ ^(400|440|600|640)$ ]]; then
echo "WARNING: wp-config.php permissions: (should be 600)"
fi

World-writable PHP files

WRITABLE=$(find "" -name "*.php" -perm /o+w 2>/dev/null | wc -l)
if [ "" -gt 0 ]; then
echo "WARNING: world-writable PHP files found"
fi
`

Each client gets flagged items in their report.

The HTML report

The script generates a per-client HTML report:


? WordPress 6.5.3 - up to date
? 12 plugins updated
? Database backup: 45 MB
? Security scan: clean
? wp-config.php permissions: 644 (should be 600)

I email this to clients monthly. It shows them the value of what I'm doing.

The uptime monitor

Separate script, runs every 10 minutes via cron:

`ash

!/bin/bash

SITES=("https://client1.com" "https://client2.com")
ALERT_EMAIL="you@yourcompany.com"

for SITE in "${SITES[@]}"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 "")
if [ "" != "200" ]; then
echo "DOWN: (HTTP )" | mail -s "SITE DOWN: " ""
fi
done
`

Results

After running this for 6 months:

  • Monthly maintenance time: 6 hours ? ~20 minutes
  • Zero missed updates
  • Caught 2 sites with world-writable PHP files
  • One client site went down at 3am - got the alert, fixed it before they noticed

The full toolkit

I packaged everything - the bulk update script (Bash + PowerShell), security audit, uptime monitor, clients.json template, HTML report template, and maintenance checklist.

WordPress Agency Automation Bundle - use code DEVTO for 20% off.

Or use the snippets above as a starting point. Either way, stop clicking "Update All" manually eight times a month.


Questions about the implementation? Drop them in the comments.


More in this series

All tools: devautomation.gumroad.com

Top comments (0)