·

WordPress e Limite Inode: Come Disattivare i Ritagli Immagini Automatici

Sui server Linux, l’esaurimento della quota Inode blocca WordPress anche con decine di Gigabyte liberi. La proliferazione incontrollata dei ritagli immagine satura il filesystem, compromettendo backup e stabilità del sistema.

1. Filesystem Linux: La differenza sostanziale tra Gigabyte e Inode

Nelle architetture server basate su kernel Linux e filesystem ext4, lo spazio di archiviazione non è definito esclusivamente dalla capienza volumetrica in Gigabyte, ma da una struttura di allocazione tabellare denominata Inode (Index Node).

Un Inode è una struttura dati che memorizza i metadati di qualsiasi risorsa memorizzata su disco: permessi di accesso (POSIX), proprietario utente e gruppo (UID/GID), timestamp e puntatori ai blocchi fisici di memoria. Non contiene il nome del file né il suo contenuto grezzo.

Filesystem Linux (ext4)
├── Tabella Inode (Metadati)
│   ├── Inode #104201 ──► [Permessi, UID] ──► Dati
│   ├── Inode #104202 ──► [Permessi, UID] ──► Dati
│   └── Inode #104203 ──► [Permessi, UID] ──► Dati
└── Limite Host: Quota fissa (es. 250.000 Inode)

Sulla maggior parte dei server Linux gestiti e dei nodi cloud condivisi, i provider impostano una soglia rigida sulla quota Inode (generalmente compresa tra 150.000 e 300.000 unità). Quando il conteggio degli Inode raggiunge il 100%, il filesystem restituisce un errore irreversibile di tipo Disk quota exceeded o No space left on device, anche se il disco presenta decine di Gigabyte nominali ancora liberi.

Le conseguenze dirette sono sistemiche:

  • Impossibilità di scrivere file di sessione PHP temporanei in /tmp.
  • Fallimento dei dump di database e dei backup notturni incrementali.
  • Blocco dell’aggiornamento automatico dei plugin e dei file di log di NGINX/Apache.

2. Il moltiplicatore di file di WordPress

L’approccio predefinito del Core di WordPress al caricamento di un file multimediale è orientato alla compatibilità retroattiva indiscriminata. Quando un redattore carica un singolo file grafico all’interno della cartella wp-content/uploads/AAAA/MM/, il framework non si limita a memorizzare il documento sorgente:

  1. Originale: foto-laboratorio.jpg
  2. Miniatura (Thumbnail): foto-laboratorio-150x150.jpg
  3. Medio (Medium): foto-laboratorio-300x200.jpg
  4. Grande (Large): foto-laboratorio-1024x683.jpg
  5. Nativo occulto (Medium Large): foto-laboratorio-768x512.jpg (introdotto per srcset e non visibile da GUI standard).
  6. Formati del tema attivo: ulteriori 3-5 ritagli registrati tramite la funzione PHP add_image_size() da temi commerciali o plugin di e-commerce.
1 Immagine Caricata  ──► Elaborazione GD/Imagick ──► 8-10 File distinti su disco
1.000 Media Caricati ──► Consumo reale su disco:   8.000 - 10.000 Inode

In cataloghi con frequenti inserimenti di prodotti o in portali editoriali ricchi di notizie, una libreria multimediale di sole 5.000 immagini porta il conteggio a oltre 50.000 file orfani, saturando la tabella dei descrittori del filesystem.

3. Disattivazione dei ritagli automatici nel Core

La risoluzione del problema richiede la neutralizzazione della pipeline di ritaglio del CMS, trasformando WordPress in un contenitore che serve direttamente l’asset ottimizzato senza manipolarlo.

A. Azzeramento da interfaccia nativa

Dal pannello di controllo, accedere a Impostazioni > Media:

  • Dimensione miniatura: impostare Larghezza a 0 e Altezza a 0 (deselezionando il ritaglio forzato).
  • Dimensione media: impostare Larghezza massima a 0 e Altezza massima a 0.
  • Dimensione grande: impostare Larghezza massima a 0 e Altezza massima a 0.

B. Disattivazione del formato nascosto “Medium Large” via WP-CLI

La misura 768px non compare nella schermata delle impostazioni. Per azzerarla a livello di database nella tabella wp_options, eseguire il comando:

wp option update medium_large_size_w 0
wp option update medium_large_size_h 0

C. Blocco architetturale programmatico (Must-Use Plugin)

Per impedire a temi o plugin attivi di registrare ulteriori dimensioni di taglio in memoria, è indispensabile intercettare il filtro di sistema intermediate_image_sizes_advanced.

Creare un file denominato disable-crops.php all’interno della cartella wp-content/mu-plugins/:

<?php
/**
 * Plugin Name:  Infrastruttura · Blocco Totale Ritagli Inode
 * Description:  Inibisce la moltiplicazione dei file nel filesystem azzerando i formati intermedi.
 * Version:       1.0.0
 * Author:        BozzaDigital
 */

defined( 'ABSPATH' ) || exit;

// Inibisce i formati intermedi generati dal core e da plugin terzi
add_filter( 'intermediate_image_sizes_advanced', function ( $sizes ) {
    return []; // Restituisce un array vuoto: nessun ritaglio sul filesystem
} );

// Disabilita la generazione del formato 'scaled' ad alta risoluzione (oltre 2560px)
add_filter( 'big_image_size_threshold', '__return_false' );

4. Pipeline a Monte: Ottimizzazione sRGB e WebP all’origine

Delegare il ridimensionamento e la compressione al motore PHP del server tramite estensioni come gd o imagick genera due inefficienze:

  1. Picchi di utilizzo di memoria RAM (memory_limit) durante l’elaborazione di sorgenti pesanti provenienti da smartphone.
  2. Compressione non deterministica priva di profilazione cromatica mirata.

La prassi enterprise impone che ogni risorsa arrivi al web server già ottimizzata per la produzione.

I requisiti del file destinato al caricamento

  • Spazio Colore: Rigorosamente sRGB. I profili AdobeRGB, ProPhoto o CMYK non sono idonei alla visualizzazione web e provocano alterazioni cromatiche e byte superflui.
  • Formato: WebP lossy con fattore di compressione bilanciato (qualità compresa tra 75 e 82).
  • Dimensioni fisiche: larghezza fissa di 1920 pixel per immagini orizzontali Above The Fold (Hero) e tra 800 e 1200 pixel per sezioni a mezza pagina o layout a colonna.
  • Peso nominale: Rigorosamente inferiore a 150 KB (target ideale per un punteggio LCP ottimale: sotto gli 80 KB).

Script Bash di pre-elaborazione locale via ImageMagick

Prima dell’upload, una cartella sorgente contenente file JPEG o PNG ad alta risoluzione può essere standardizzata tramite un comando da terminale prima del deployment:

#!/usr/bin/env bash
# Ridimensionamento max 1920px e conversione spazio colore sRGB
# Strip metadati EXIF e compressione WebP qualita 80%

for file in *.{jpg,jpeg,png}; do
  [ -f "$file" ] || continue
  output="${file%.*}.webp"
  magick "$file" \
    -resize "1920x1920>" \
    -colorspace sRGB \
    -strip \
    -quality 80 \
    "$output"
  echo "[OTTIMIZZATO] $file -> $output"
done

5. Bonifica dello storico e recupero degli Inode

Dopo aver configurato il blocco sui futuri caricamenti, è necessario eliminare le decine di migliaia di file ridondanti già accumulati sul server.

Controllo preliminare degli Inode utilizzati

Verificare lo stato attuale della partizione dal terminale SSH:

df -i

Rimozione massiva dei ritagli generati

I ritagli intermedi di WordPress presentano una convenzione di denominazione prevedibile che include le dimensioni fisiche al termine del nome file (es. -300x200.webp o -150x150.jpg).

Dalla cartella principale degli upload (wp-content/uploads/), è possibile identificare e rimuovere i file intermedi con un comando find:

# Esecuzione preventiva di test (conteggio dei file identificati)
find . -type f -regextype posix-extended -regex '.*-[0-9]+x[0-9]+.(jpg|jpeg|png|webp)' | wc -l

# Rimozione definitiva dei file di ritaglio intermedi
find . -type f -regextype posix-extended -regex '.*-[0-9]+x[0-9]+.(jpg|jpeg|png|webp)' -delete

L’eliminazione dei ritagli fisici azzera la frammentazione del disco, riporta il consumo di Inode entro i parametri contrattuali dell’hosting e velocizza le operazioni di backup notturne. Mantenendo il controllo della compressione sul terminale di sviluppo, il caricamento delle pagine risulta istantaneo e privo di latenze di elaborazione server-side.

💡 Fuori dal terminale: cosa significa in parole povere?

  • Il problema reale: Immagina il server come un archivio con due limiti fisici: i chili di carta che può contenere (i Gigabyte) e il numero totale di cartellette disponibili (gli Inode). Se hai spazio per 100 quintali ma il fornitore ti assegna solo 1.000 cartellette, appena crei la cartelletta 1.001 l’archivio si blocca, anche se le stanze sono mezze vuote.
  • Cosa fa WordPress di default: Ogni volta che carichi una singola foto, ne crea di nascosto altre 8 o 10 in formati diversi. Bastano poche centinaia di immagini per esaurire tutte le “cartellette”, mandando in tilt backup notturni, aggiornamenti e l’intero sito web.
  • La nostra soluzione: Abbiamo ordinato al sistema di salvare esclusivamente l’immagine originale, già compressa e ottimizzata all’origine. Risultato: zero file spazzatura, backup notturni fulminei e la certezza matematica che il server non andrà mai in blocco per esaurimento Inode.

Daniele Bozza

Unicorn Designer | Web Developer & Security · WordPress & PrestaShop · BozzaDigital

Trasformo siti lenti e vulnerabili in architetture blindate, veloci e prive di plugin commerciali. Il blog su cui stai navigando è il nostro standard: codice pulito, conformità GDPR nativa e Core Web Vitals al 100%.

Disclaimer Tecnico: I comandi di terminale, le architetture e il codice riportati in questo articolo sono forniti a scopo didattico e informativo «così come sono». Prima di applicarli in produzione, testali sempre in un ambiente di staging isolato con backup verificati. Per approfondire, consulta le nostre Note Legali e Disclaimer Tecnico.