WP-CLI: Backup e Ripristino Database WordPress Automatizzato

5 giugno 20269 minGuide
In breveAI

Guida tecnica completa all'uso di WP-CLI per backup e ripristino automatizzato di database WordPress, con comandi avanzati, automazione cron e best practice per agenzie.

Perché usare WP-CLI per i backup database

Gestire decine o centinaia di siti WordPress client richiede processi di backup affidabili e ripetibili. WP-CLI offre un controllo granulare sul database che i plugin GUI non possono eguagliare: niente timeout PHP, niente limiti di memoria, accesso diretto via SSH e automazione completa tramite script.

Secondo i dati di utilizzo di AgencyPilot, le agenzie che implementano backup automatizzati via WP-CLI riducono del 73% il tempo dedicato alla gestione dei backup rispetto all’uso esclusivo di plugin. La capacità di scriptare ogni operazione elimina errori umani e permette di standardizzare i processi su tutta la flotta di siti client.

I vantaggi principali:

  • Nessun limite di esecuzione PHP o memoria
  • Export selettivi per tabelle specifiche
  • Compressione nativa e ottimizzazione automatica
  • Integrazione diretta con storage remoto (S3, rsync, etc)
  • Log dettagliati e gestione errori programmatica

Comandi base per export database

Il comando fondamentale per l’export è wp db export. La sintassi base crea un dump SQL nella directory corrente:

wp db export

Per un controllo maggiore, specifica il nome file e abilita la compressione:

wp db export backup-$(date +%Y%m%d-%H%M%S).sql.gz

Questo crea file con timestamp automatico, essenziale per mantenere storico ordinato. Il formato .gz attiva automaticamente la compressione gzip, riducendo le dimensioni del 85-95% per database tipici.

Opzioni avanzate di export

WP-CLI offre flag potenti per personalizzare l’export:

  • --tables: esporta solo tabelle specifiche (wp db export --tables=wp_posts,wp_postmeta backup.sql)
  • --exclude_tables: esclude tabelle pesanti come cache o log
  • --add-drop-table: include statement DROP TABLE (utile per ripristini puliti)
  • --default-character-set: forza charset specifico (importante per utf8mb4)
  • --single-transaction: dump consistente senza lock tabelle (InnoDB)

Esempio pratico per backup production senza tabelle di cache:

wp db export backup-production.sql.gz \
  --exclude_tables=wp_wc_session,wp_statistics_visitor \
  --add-drop-table \
  --single-transaction

Per siti WooCommerce o con molti dati transitori, escludere tabelle temporanee riduce dimensioni e tempi di export del 40-60%.

Import e ripristino database

Il comando wp db import gestisce il ripristino. Accetta file SQL compressi o non compressi:

wp db import backup-20260520-143022.sql.gz

WP-CLI rileva automaticamente la compressione gzip e decomprime al volo. Per file molto grandi (oltre 1GB compressi), considera di aumentare i timeout MySQL:

wp db query "SET GLOBAL max_allowed_packet=1073741824;"

Workflow sicuro di ripristino

Prima di importare un backup su un sito esistente, segui questo workflow:

  1. Crea backup dello stato attuale: wp db export pre-restore-backup.sql.gz
  2. Verifica integrità file backup: gunzip -t backup.sql.gz
  3. Opzionale: resetta database: wp db reset --yes
  4. Importa: wp db import backup.sql.gz
  5. Verifica tabelle: wp db check
  6. Ottimizza: wp db optimize

Il comando wp db reset elimina tutte le tabelle WordPress esistenti, garantendo un ambiente pulito. Usalo con cautela e sempre dopo un backup preventivo.

Gestione errori durante import

Gli import possono fallire per vari motivi. Diagnostica con:

wp db import backup.sql.gz --debug 2>&1 | tee import.log

Errori comuni e soluzioni:

  • max_allowed_packet too small: aumenta in my.cnf o via query SET GLOBAL
  • Table doesn’t exist: il backup è parziale, verifica l’export originale
  • Incorrect string value: problema charset, usa wp db import --default-character-set=utf8mb4
  • Disk full: MySQL ha bisogno di spazio temporaneo (1.5x dimensione import)

Automazione backup con cron

L’automazione trasforma WP-CLI da strumento manuale a sistema di backup enterprise. Crea uno script bash /usr/local/bin/wp-backup.sh:

#!/bin/bash
SITE_PATH="/var/www/html"
BACKUP_DIR="/backups/mysql"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d-%H%M%S)

# Export database
cd $SITE_PATH
wp db export $BACKUP_DIR/db-$DATE.sql.gz \
  --add-drop-table \
  --single-transaction \
  --exclude_tables=wp_statistics_*,wp_wc_session*

# Verifica successo
if [ $? -eq 0 ]; then
  echo "Backup completato: db-$DATE.sql.gz"
  
  # Rimuovi backup vecchi
  find $BACKUP_DIR -name "db-*.sql.gz" -mtime +$RETENTION_DAYS -delete
  
  # Sync su S3 (opzionale)
  # aws s3 sync $BACKUP_DIR s3://bucket-backups/$(basename $SITE_PATH)/
else
  echo "ERRORE: Backup fallito" >&2
  exit 1
fi

Rendi eseguibile e aggiungi a crontab:

chmod +x /usr/local/bin/wp-backup.sh
crontab -e

Aggiungi entry per backup giornaliero alle 2:00 AM:

0 2 * * * /usr/local/bin/wp-backup.sh >> /var/log/wp-backup.log 2>&1

Backup differenziati per retention policy

Implementa una strategia 3-2-1 (3 copie, 2 media, 1 offsite) con frequenze diverse:

  • Giornalieri: retention 7 giorni, ore 02:00
  • Settimanali: retention 4 settimane, domenica 03:00
  • Mensili: retention 12 mesi, primo del mese 04:00

Script modificato con logica retention:

BACKUP_TYPE="daily" # daily, weekly, monthly
case $BACKUP_TYPE in
  daily)
    RETENTION=7
    BACKUP_DIR="/backups/daily"
    ;;
  weekly)
    RETENTION=28
    BACKUP_DIR="/backups/weekly"
    ;;
  monthly)
    RETENTION=365
    BACKUP_DIR="/backups/monthly"
    ;;
esac

Backup multi-sito e gestione centralizzata

Per agenzie con decine di siti, centralizza i backup con uno script master che itera su tutti i client:

#!/bin/bash
SITES_FILE="/etc/wp-sites.conf"

while IFS=',' read -r site_name site_path; do
  echo "Backup $site_name..."
  
  cd $site_path
  wp db export /backups/$site_name/db-$(date +%Y%m%d).sql.gz \
    --add-drop-table \
    --single-transaction || echo "FAILED: $site_name" >> /var/log/backup-errors.log
    
done < $SITES_FILE

File /etc/wp-sites.conf:

cliente1,/var/www/cliente1.com
cliente2,/var/www/cliente2.com
cliente3,/var/www/cliente3.com

Per siti WordPress multisite, usa il flag --network per operare su tutti i subsites o specifica --url=subsite.example.com per singoli siti della rete.

Monitoraggio e alerting

Integra controlli di successo con notifiche. Esempio con curl verso webhook:

if [ $? -eq 0 ]; then
  curl -X POST https://monitor.agencypilot.it/webhook/backup-success \
    -H "Content-Type: application/json" \
    -d '{"site":"'$site_name'","size":'$(stat -f%z $backup_file)',"timestamp":'$(date +%s)'}'
else
  curl -X POST https://monitor.agencypilot.it/webhook/backup-failed \
    -d '{"site":"'$site_name'","error":"'$(tail -1 /var/log/backup.log)'"}'
fi

AgencyPilot integra nativamente questi webhook per dashboard centralizzata di backup status su tutti i siti client.

Ottimizzazioni e best practice

Dopo anni di gestione backup su migliaia di siti, queste pratiche fanno la differenza:

Performance

  • Usa --single-transaction sempre su InnoDB per evitare lock
  • Escludi tabelle di log e cache (riduzione 40-70% tempi export)
  • Comprimi sempre con gzip: il rapporto CPU/spazio è favorevole
  • Pianifica backup in orari di basso traffico (02:00-05:00)
  • Su database oltre 5GB, valuta mydumper per parallelizzazione

Sicurezza

  • Cripta backup sensibili: gpg -c backup.sql.gz
  • Imposta permessi restrittivi: chmod 600 sui file backup
  • Usa directory separate per sito, non accessibili via web
  • Rotazione automatica: mai superare retention policy definite
  • Test ripristino mensile su ambiente staging

Affidabilità

  • Verifica integrità: gunzip -t backup.sql.gz post-export
  • Mantieni almeno 3 generazioni di backup prima di eliminare
  • Backup offsite obbligatorio: S3, Backblaze B2, rsync remoto
  • Log dettagliati con timestamp e codici uscita
  • Monitoring attivo: alerting su mancati backup entro 25 ore

Comando di verifica completo

Script per verificare sanità backup recenti:

#!/bin/bash
BACKUP_DIR="/backups/daily"
MAX_AGE_HOURS=25

# Trova backup più recente
LATEST=$(find $BACKUP_DIR -name "db-*.sql.gz" -mtime -1 -print -quit)

if [ -z "$LATEST" ]; then
  echo "ERRORE: Nessun backup recente trovato"
  exit 1
fi

# Verifica integrità
if gunzip -t "$LATEST" 2>/dev/null; then
  SIZE=$(du -h "$LATEST" | cut -f1)
  echo "OK: Backup valido ($SIZE) - $LATEST"
  exit 0
else
  echo "ERRORE: Backup corrotto - $LATEST"
  exit 1
fi

Integrazione con storage remoto

I backup locali non bastano. Sincronizza automaticamente su storage remoto:

Amazon S3

aws s3 sync /backups/daily/ s3://bucket-backups/cliente1/daily/ \
  --storage-class STANDARD_IA \
  --delete

Backblaze B2 (più economico)

b2 sync --deleteRemoved /backups/daily/ b2://bucket-backups/cliente1/daily/

rsync su server remoto

rsync -avz --delete /backups/daily/ backup-server:/backups/cliente1/daily/

Per gestione enterprise, AgencyPilot offre sincronizzazione automatica configurabile via UI, con deduplicazione e versioning inclusi.

Restore avanzati e migrazione

Scenari comuni che richiedono approcci specifici:

Migrazione tra domini

Dopo import, aggiorna URL con search-replace:

wp db import backup.sql.gz
wp search-replace 'vecchiodomain.com' 'nuovodomain.com' \
  --all-tables \
  --report-changed-only

Ripristino selettivo tabelle

Estrai singole tabelle da backup completo:

# Estrai solo wp_posts
zcat backup.sql.gz | sed -n '/DROP TABLE.*`wp_posts`/,/UNLOCK TABLES/p' > wp_posts.sql
wp db query < wp_posts.sql

Clone per staging

Workflow completo per duplicare production su staging:

#!/bin/bash
PROD_PATH="/var/www/production"
STAG_PATH="/var/www/staging"

# Export da production
cd $PROD_PATH
wp db export /tmp/prod-clone.sql.gz

# Import su staging
cd $STAG_PATH
wp db import /tmp/prod-clone.sql.gz

# Aggiorna URL
wp search-replace 'production.com' 'staging.production.com' --all-tables

# Disabilita indicizzazione
wp option update blog_public 0

# Flush cache
wp cache flush

rm /tmp/prod-clone.sql.gz

FAQ

Quanto spazio disco servono per i backup database WordPress?

Un database WordPress tipico di un sito aziendale (5000-10000 post) occupa 50-150MB non compresso. Con compressione gzip, si riduce a 5-15MB. Per un e-commerce WooCommerce medio (1000 prodotti, 5000 ordini) considera 200-400MB non compresso, 20-40MB compresso. Pianifica spazio per retention: 30 giorni di backup giornalieri richiedono circa 30x la dimensione compressa, più 50% di buffer. Per 100 siti client con media 20MB compresso: circa 60-80GB totali con retention 30 giorni.

Posso fare backup durante orario di picco senza rallentare il sito?

Sì, usando --single-transaction con database InnoDB. Questo flag crea uno snapshot consistente senza bloccare le tabelle. Il database rimane completamente operativo durante l'export. L'unico impatto è CPU e I/O disco, trascurabili su server moderni con SSD. Evita --lock-tables che blocca scritture. Su database molto grandi (oltre 10GB) o con dischi HDD lenti, pianifica comunque backup notturni per minimizzare contention su I/O.

Come verifico che un backup sia ripristinabile prima di un'emergenza?

Implementa test di ripristino automatizzati mensili: crea un container Docker o VM temporanea, importa l'ultimo backup, esegui wp db check e verifica query base come wp post list --post_type=page. Script di test basilare: docker run --rm -v /backups:/backup wordpress:cli wp db import /backup/latest.sql.gz && wp db check. Considera che il 12% dei backup fallisce al ripristino per corruzione o incompatibilità non rilevate. Test regolari sono l'unica garanzia.

Meglio un plugin di backup o WP-CLI per gestione multi-sito?

Per agenzie con più di 10 siti, WP-CLI è superiore: consente automazione centralizzata, nessun overhead per sito, storage unificato e costi zero di licensing. I plugin hanno vantaggi su setup singoli o per clienti non tecnici (UI, restore semplificato). Dati AgencyPilot: agenzie con 50+ siti risparmiano 15-20 ore/mese passando a backup WP-CLI centralizzati. Il ROI si raggiunge già con 5-10 siti gestiti. L'approccio ibrido funziona: WP-CLI per backup automatici, plugin come safety net per restore emergenziale via UI.

Come gestire backup di database WordPress molto grandi (oltre 5GB)?

Per database oltre 5GB considera: 1) escludi tabelle non critiche (log, statistiche, cache) che puoi ridurre dimensioni del 60-80%, 2) usa mydumper invece di mysqldump per export parallelo multi-thread, 3) incrementa max_allowed_packet e net_buffer_length in MySQL, 4) split export per tabella con script custom, 5) valuta backup incrementali con tool come Percona XtraBackup per copie binary-level. WP-CLI standard gestisce bene fino a 10-15GB, oltre serve ottimizzazione. Maggiori dettagli nella nostra guida ottimizzazione database WordPress di grandi dimensioni.

Gestisci i siti WordPress dei tuoi clienti?

AgencyPilot ti dà report AI, uptime monitoring, backup e portale clienti in un’unica dashboard. Gratis per 3 siti.

Prova gratis
Leggi anche
Tutti gli articoli
Tutti gli articoli