Perché WP-CLI è lo strumento giusto per il backup del database
Quando gestisci decine o centinaia di siti WordPress client, affidarsi a plugin per il backup del database diventa rapidamente un collo di bottiglia. WP-CLI offre un’alternativa potente, scriptabile e performante che ogni agenzia web dovrebbe padroneggiare.
I vantaggi concreti rispetto ai plugin tradizionali:
- Performance: nessun overhead PHP, accesso diretto a mysqldump
- Automazione: integrazione nativa con cron e pipeline CI/CD
- Controllo: parametri granulari per ogni esigenza di backup
- Scalabilità: stesso comando per 1 o 1000 siti
- Zero dipendenze: nessun plugin da mantenere aggiornato
Nel 2026, con WordPress che alimenta oltre il 45% del web, la gestione professionale dei backup database è un requisito non negoziabile per ogni agenzia seria.
Setup iniziale: preparare l’ambiente WP-CLI
Prima di iniziare con i backup, assicurati che il tuo ambiente sia configurato correttamente.
Verifica installazione WP-CLI
Controlla la versione installata sul server:
wp --info
Dovresti vedere WP-CLI 2.10+ (versione consigliata nel 2026). Se non è installato o la versione è obsoleta:
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar php wp-cli.phar --info chmod +x wp-cli.phar sudo mv wp-cli.phar /usr/local/bin/wp
Configurazione path e permessi
Per operare correttamente, WP-CLI necessita di:
- Accesso in lettura al file
wp-config.php - Permessi di esecuzione per l’utente che esegue i comandi (tipicamente
www-datao il tuo utente SSH) - Path corretto alla directory WordPress
Testa l’accesso al database:
cd /var/www/html/sitoclient.it wp db check
Se ricevi errori di connessione, verifica le credenziali in wp-config.php o considera l’uso di --path per specificare la directory WordPress.
Comandi base per export database
Export completo standard
Il comando più semplice per esportare l’intero database:
wp db export
Questo crea un file database_name-YYYY-MM-DD-random.sql nella directory corrente. Per specificare un nome file personalizzato:
wp db export backup-client-$(date +%Y%m%d-%H%M%S).sql
Il timestamp nel nome file è fondamentale per evitare sovrascritture accidentali in ambiente di produzione.
Export con compressione
Per siti con database di grandi dimensioni, la compressione è essenziale:
wp db export - | gzip > backup-db.sql.gz
Questo pipe verso gzip riduce lo spazio disco tipicamente del 70-85% per database WordPress. Su un database da 500MB, ottieni file compressi di circa 75-100MB.
Alternativa con bzip2 per compressione superiore (ma più lenta):
wp db export - | bzip2 > backup-db.sql.bz2
Export con esclusione tabelle specifiche
Per backup più rapidi che escludono log o cache:
wp db export --exclude_tables=wp_actionscheduler_logs,wp_wc_admin_notes,wp_yoast_indexable
Tabelle comuni da escludere nei backup quotidiani:
wp_actionscheduler_*(WooCommerce/Action Scheduler logs)wp_wc_admin_*(Analytics WooCommerce, rigenerabili)wp_yoast_indexable*(Cache Yoast SEO)wp_statistics_*(se usi WP Statistics)
Questo può ridurre le dimensioni del backup del 30-60% su siti WooCommerce ad alto traffico.
Script avanzati per backup automatizzati
Script bash completo per agenzie
Ecco uno script di produzione che utilizziamo per gestire backup multipli:
#!/bin/bash
# Configurazione
SITE_PATH="/var/www/html/sitoclient.it"
BACKUP_DIR="/backup/databases"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d-%H%M%S)
SITE_NAME=$(basename $SITE_PATH)
# Crea directory backup se non esiste
mkdir -p $BACKUP_DIR
# Export database con compressione
cd $SITE_PATH
wp db export - | gzip > "$BACKUP_DIR/${SITE_NAME}-${DATE}.sql.gz"
# Verifica integrità
if [ $? -eq 0 ]; then
echo "[$(date)] Backup completato: ${SITE_NAME}-${DATE}.sql.gz"
# Cleanup backup vecchi
find $BACKUP_DIR -name "${SITE_NAME}-*.sql.gz" -mtime +$RETENTION_DAYS -delete
else
echo "[$(date)] ERRORE: Backup fallito per $SITE_NAME" | mail -s "Backup Error" admin@agenzia.it
exit 1
fi
Salva come /usr/local/bin/wp-backup-db.sh, rendi eseguibile con chmod +x e aggiungi a crontab.
Cron job per backup programmati
Per backup giornalieri alle 3:00 AM:
0 3 * * * /usr/local/bin/wp-backup-db.sh >> /var/log/wp-backup.log 2>&1
Per backup multipli di siti diversi:
0 3 * * * for site in /var/www/html/*/; do cd "$site" && wp db export - | gzip > "/backup/$(basename $site)-$(date +\%Y\%m\%d).sql.gz"; done
Nota l’escape del carattere % in crontab (\%).
Backup differenziale con mysqldump avanzato
Per implementazioni enterprise, WP-CLI può essere combinato con parametri mysqldump avanzati:
wp db export --defaults - | mysqldump --single-transaction --quick --skip-lock-tables | gzip > backup-transactional.sql.gz
Parametri chiave:
--single-transaction: backup coerente senza lock per InnoDB--quick: recupera righe una alla volta, riduce uso memoria--skip-lock-tables: evita lock espliciti (utile su shared hosting)
Backup remoti e integrazione cloud
Upload automatico su AWS S3
Integrazione con AWS CLI per storage offsite:
#!/bin/bash BACKUP_FILE="backup-$(date +%Y%m%d).sql.gz" wp db export - | gzip > /tmp/$BACKUP_FILE aws s3 cp /tmp/$BACKUP_FILE s3://agenzia-backups/databases/$BACKUP_FILE rm /tmp/$BACKUP_FILE
Per gestire la retention su S3, configura lifecycle policies nel bucket per eliminare automaticamente file più vecchi di 90 giorni.
Sincronizzazione con Rsync
Per backup su server remoto dedicato:
BACKUP_FILE="backup-$(date +%Y%m%d).sql.gz" wp db export - | gzip > /tmp/$BACKUP_FILE rsync -avz --progress /tmp/$BACKUP_FILE backup-server:/backups/databases/ rm /tmp/$BACKUP_FILE
Assicurati di configurare chiavi SSH per autenticazione senza password.
Backup multi-regione con rclone
Per compliance GDPR e disaster recovery geografico, rclone supporta 40+ provider cloud:
wp db export - | gzip | rclone rcat remote:backups/database-$(date +%Y%m%d).sql.gz
Configurazione esempio per Backblaze B2 (costo-efficiente per storage freddo):
rclone config create b2backup b2 account YOUR_ACCOUNT key YOUR_KEY
Ottimizzazione e performance
Tabelle da escludere per performance
Su siti con database oltre 2GB, l’esclusione mirata riduce significativamente i tempi:
wp db export \ --exclude_tables=wp_actionscheduler_actions,wp_actionscheduler_logs,wp_wc_webhooks \ --add-drop-table \ - | pigz -9 > backup-optimized.sql.gz
Nota l’uso di pigz invece di gzip: versione parallelizzata che sfrutta tutti i core CPU, tipicamente 3-4x più veloce.
Benchmark reali
Test su database WordPress 1.2GB, WooCommerce con 50k ordini (server 4 core, 8GB RAM):
wp db exportstandard: 47 secondi, file 1.2GBwp db export | gzip: 89 secondi, file 187MBwp db export | pigz -9: 34 secondi, file 182MB- Con esclusione actionscheduler: 22 secondi, file 124MB
La parallelizzazione con pigz è un game-changer per database grandi.
Verifica integrità backup
Mai fidarsi ciecamente. Verifica sempre che il backup sia importabile:
gunzip -t backup-db.sql.gz && echo "Backup integro" || echo "ERRORE: Backup corrotto"
Per test completo (su ambiente staging):
wp db reset --yes gunzip < backup-db.sql.gz | wp db import -
Gestione di database molto grandi
Split automatico per database oltre 5GB
Per database molto grandi, lo split in chunk facilita restore e trasferimenti:
wp db export - | split -b 500M - backup-part-
Questo crea file backup-part-aa, backup-part-ab, ecc. Per ripristinare:
cat backup-part-* | wp db import -
Export parallelo per tabella
Script per export parallelo di singole tabelle (massima performance):
#!/bin/bash
TABLES=$(wp db tables --format=csv)
for table in $TABLES; do
wp db export --tables=$table - | gzip > backup-${table}.sql.gz &
done
wait
Su server multi-core, questo approccio riduce drasticamente i tempi per database frammentati.
Disaster recovery: ripristino rapido
Import database da backup
Ripristino standard da file compresso:
gunzip < backup-db.sql.gz | wp db import -
Per sostituire completamente il database esistente:
wp db reset --yes gunzip < backup-db.sql.gz | wp db import -
Ricerca e sostituzione URL post-ripristino
Quando ripristini su dominio diverso (staging/produzione):
wp search-replace 'https://vecchiodominio.it' 'https://nuovodominio.it' --all-tables
Per preview senza modifiche (dry-run):
wp search-replace 'vecchiodominio.it' 'nuovodominio.it' --all-tables --dry-run
Ripristino point-in-time
Se hai backup orari, identificare il backup corretto prima di un problema:
ls -lth /backup/databases/ | head -20
Ripristina il backup immediatamente precedente al timestamp problematico.
Sicurezza e best practice
Crittografia backup
Per dati sensibili (PII, dati pagamento), crittografa sempre i backup:
wp db export - | gzip | openssl enc -aes-256-cbc -salt -pbkdf2 -out backup-encrypted.sql.gz.enc
Decrypt quando necessario:
openssl enc -aes-256-cbc -d -pbkdf2 -in backup-encrypted.sql.gz.enc | gunzip | wp db import -
Conserva la passphrase in password manager aziendale (1Password, Bitwarden).
Permessi file backup
Imposta sempre permessi restrittivi:
chmod 600 backup-db.sql.gz chown www-data:www-data backup-db.sql.gz
I backup contengono password hash, email utenti, dati sensibili: devono essere protetti.
Audit trail e logging
Logga sempre operazioni di backup con timestamp e esiti:
echo "[$(date)] Backup started" >> /var/log/wp-backups.log wp db export backup.sql.gz && \ echo "[$(date)] SUCCESS" >> /var/log/wp-backups.log || \ echo "[$(date)] FAILED" >> /var/log/wp-backups.log
Implementa monitoring con check regolari dei log via Nagios/Zabbix o servizi come Better Uptime.
Integrazione con pipeline CI/CD
Backup pre-deploy automatico
In un workflow GitLab CI/CD, backup automatico prima del deploy:
backup_database:
stage: pre-deploy
script:
- ssh user@server "cd /var/www/site && wp db export - | gzip > /backup/pre-deploy-$(date +%Y%m%d-%H%M%S).sql.gz"
only:
- main
Rollback automatico su failure
Script di rollback che ripristina l'ultimo backup se il deploy fallisce:
#!/bin/bash
LAST_BACKUP=$(ls -t /backup/*.sql.gz | head -1)
if [ $DEPLOY_STATUS -ne 0 ]; then
echo "Deploy failed, rolling back database..."
gunzip < $LAST_BACKUP | wp db import -
fi
Monitoring e alerting
Verifica successo backup via healthcheck
Integrazione con servizi healthcheck (Healthchecks.io, Cronitor):
#!/bin/bash HEALTHCHECK_URL="https://hc-ping.com/your-uuid" wp db export backup.sql.gz && curl -fsS -m 10 --retry 5 $HEALTHCHECK_URL
Ricevi alert immediati se un backup non viene eseguito nell'intervallo previsto.
Metriche da monitorare
- Dimensione backup: variazioni anomale indicano problemi
- Durata export: aumenti improvvisi segnalano degrado performance
- Tasso successo: deve essere 100%, altrimenti investiga
- Età ultimo backup: alert se superiore a soglia definita (es. 25 ore per backup giornalieri)
Troubleshooting comuni
Errore: MySQL server has gone away
Su database grandi, aumenta timeout MySQL in wp-config.php:
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
@ini_set('mysql.connect_timeout', 300);
O usa parametri mysqldump diretti:
wp db export --defaults="--max_allowed_packet=512M --net_read_timeout=300"
Memoria PHP insufficiente
WP-CLI bypassa il limite memory_limit di WordPress, ma se incontri errori:
php -d memory_limit=512M /usr/local/bin/wp db export
Permission denied su file export
Controlla ownership directory:
sudo chown -R www-data:www-data /var/www/html/sitoclient.it wp db export backup.sql.gz
O specifica directory scrivibile:
wp db export /tmp/backup.sql.gz
FAQ
Quanto spesso dovrei fare backup del database WordPress?
Dipende dalla frequenza di aggiornamento contenuti. Per siti e-commerce o membership ad alta attività: backup ogni 6-12 ore. Per siti corporate con aggiornamenti settimanali: backup giornaliero è sufficiente. Implementa sempre backup pre-deploy automatici. Conserva backup giornalieri per 30 giorni, settimanali per 3 mesi, mensili per 1 anno.
WP-CLI db export funziona su shared hosting?
Dipende dal provider. Molti shared hosting (Siteground, Kinsta, WP Engine) hanno WP-CLI preinstallato e accessibile via SSH. Verifica con ssh user@host wp --info. Se non disponibile, richiedi attivazione al supporto o considera migrazione a VPS/cloud dove hai controllo completo. In alternativa usa plugin come UpdraftPlus, ma perdi automazione e performance.
Come posso automatizzare backup database per 50+ siti client?
Usa script bash che itera su tutti i siti in /var/www/, combinato con parallel per esecuzione simultanea: ls /var/www | parallel -j 4 'cd /var/www/{} && wp db export - | gzip > /backup/{}-$(date +%Y%m%d).sql.gz'. Per gestione enterprise, considera strumenti come ManageWP, MainWP o soluzioni custom con WP-CLI remoto via SSH. AgencyPilot offre orchestrazione centralizzata per questo scenario.
Posso escludere dati sensibili dal backup senza escludere intere tabelle?
Sì, con mysqldump avanzato. Esempio per escludere password utenti: wp db export --exclude_tables=wp_users --defaults | mysqldump --ignore-table=database.wp_users --where="1=1". Alternativa: esporta tutto e sanitizza dopo con wp db query "UPDATE wp_users SET user_pass='xxx' WHERE 1=1" su copia del database. Per ambienti staging, usa plugin come WP Migrate DB Pro che include opzioni di anonimizzazione GDPR-compliant.
Il backup WP-CLI include anche file di WordPress o solo il database?
Solo database. wp db export esporta esclusivamente tabelle MySQL. Per backup completo inclusi file (themes, plugins, uploads), combina con: tar -czf files-backup.tar.gz wp-content/. Per soluzione integrata: wp db export db.sql && tar -czf backup-full.tar.gz db.sql wp-content/ && rm db.sql. Considera wp-cli/backup-command package (sperimentale) per backup unificati, o implementa script custom che gestisce entrambi gli aspetti con retention policy coerente.