Immagini WordPress su CDN con Amazon Cloudfront (con o senza plugin)
da Massimo Della Rovere · pubblicato il 7 Agosto, 2017 · modificato il 8 Agosto, 2017

Oggi i servizi CDN (content delivery network) stanno diventando molto importanti per chi deve sviluppare un’applicazione web, a prescindere dal sistema utilizzato. Infatti le risorse multimediali rappresentano una buona parte di una pagina web, e poter delegare questo carico di lavoro rende il nostro server più performante e più semplice da gestire.

Vantaggi di una CDN

Quando un browser esegue una richiesta HTTP/HTTPS al nostro server non solo accede alla pagina HTML richiesta ma esegue tante richieste HTTP diverse in base al numero delle risorse esterne indicate nel codice HTML. Come ad esempio, immagini, fogli di stile, script javascript, file audio, file video, etc, etc. Usare un servizio CDN significa che le richieste successive del browser richiedente non saranno eseguite verso il nostro server ma verso il servizio CDN che si preoccuperà di servire le risorse statiche. Questo a grande benefico del nostro server che riceverà solo le richieste principali come pagine PHP, Java, ASP, etc etc.

In realtà questo è stato solo il vantaggio principale per cui sono state create le CDN, ma dato che la tecnologia va sempre avanti, negli ultimi anni i vantaggi sono diventati molti di più, molti fornitori hanno cercando di aggiungere servizi più specializzati a tutto ciò che riguardava la distribuzione dei contenuti multimediali, come immagini e/o streaming di video. Vi indico qui di seguito quelli che secondo me sono i vantaggi principali di una CDN moderna:

  • Geolocalizzazione: i dati non vengono memorizzati solo in una posizione geografica, ma vengono replicati in edge location differenti, questo non solo assicura un backup nativo ma da la possibilità al provider di servire la risorsa dal punto geografico più vicino rispetto alla richiesta ricevuta. Ovviamente tutto a benefico di una latenza più bassa.
  • Controllo accessi: normalmente le risorse statiche sono pubbliche e quindi è possibile accedere ad esse liberamente, però ci sono alcuni casi come ad esempio un download solo per gli iscritti, lo streaming video solo per chi ha pagato, etc, in cui serve avere un token di autorizzazione per accedere alla risorsa. Molte CDN moderne danno questo servizio.
  • Sistema di cache: oltre al fatto che i servizi di CDN gestiscono dei sistemi di cache interni che aiutano ad essere più veloci, è anche possibile decidere un tempo di cache oltre il quale il provider CDN deve riacquisire la nostra risorsa da una copia del server. Alcune CDN permettono anche di stabilire dei valori personalizzabili diversi dal tipo di risorsa.
  • Alta disponibilità: rispetto alla soluzione tradizionale, i servizi di CDN garantiscono una continuità di servizio più elevata rispetto alla nostra soluzione standard e garantiscono una protezione del dato più alta, in quanto il backup è nativo nella funzione stessa, infatti viene replicato su diverse locazioni. Ovviamente i backup tradizionali è sempre meglio farli.
  • HTTP/2: servizi di CDN come ad esempio Amazon Cloudfront danno la possibilità di attivare il protocollo HTTP/2 facendo una richiesta HTTP tradizionale al nostro server, questo aiuta ad ottenere in modo immediato dei benefici di performance senza modifiche al server. Su questo argomento casomai farò un’articolo a parte che riguarda le CDN dinamiche.

Ovviamente le caratteristiche tecniche dipendono anche dal servizio che viene utilizzato, se cercate in internet troverete decine di buoni servizi ed ognuno con qualche sua caratteristica particolare. Per quanto mi riguarda, come molti miei lettori sanno, io uso i servizi di Amazon chiamati gli Amazon Web Services di cui Cloudfront è il servizio dedicato alla CDN.

Amazon Cloudfront

Per usare il servizio di Amazon Cloudfront bisogna essere in possesso di un’account Amazon ed essersi registrati sul portale degli Amazon Web Services. Il servizio può prendere le risorse da un bucket S3 o direttamente da un server. In questo articolo useremo la tecnica di memorizzare le risorse su un bucket S3 in modo da rendere facoltativa la scelta di Cloudfront, infatti anche con solo il servizio S3 è possibile ottenere una CDN che non avrà tutti i vantaggi elencati ma si otterranno caratteristiche più che sufficienti alla maggior parte delle necessità.

WordPress & CDN

Se come me, vi capita spesso di utilizzare WordPress in alcuni progetti web, saprete bene che in WordPress le risorse vengono memorizzate nella cosidetta Libreria Multimediale, la quale non si occupa solo di memorizzare le risorse caricate su una cartella locale, ma provvede anche a creare diverse dimensioni di immagine che possono essere utilizzate in ambiti diversi, come ad esempio miniature di un post, risorse in modalità responsive, versioni quadrate, etc etc.

Purtroppo il problema di tutto questo è che il codice del core è stato scritto pensando ad una memorizzazione locale del dato e non è possibile al momento modificare questa caratteristica senza intervenire sul codice o senza installare qualche plugin dedicato. La cosa buona però è che se vogliamo cambiare il codice non dobbiamo eseguire delle operazioni troppo complicate e possiamo raggiungere il risultato cambiando adeguatamente alcuni filtri di WordPress.

WordPress & Plugin

Per iniziare vi presento due plugin che possono aiutarvi a spostare le vostre risorse su una CDN senza mettere le mani al codice. Il primo è JetPack che molti di voi userete già per altre funzioni, il secondo invece è WP Offload S3 che io uso in alcuni siti con la versione PRO e devo dire che oltre a funzionare bene da tempo non mi ha mai dato grandi problemi.

JetPack Photon: è semplice da attivare e ha il vantaggio che molti utenti lo usano già per altre funzionalità. Come svantaggio ha che alcune volte ho riscontrato che non è performante come fanno credere e in ogni caso ha delle limitazioni che è bene che andiate a leggere prima di farlo diventare la vostra soluzione CDN predefinita. Ad esempio non ha invalidazione, quindi la cache della risorsa è per sempre, non supporta tutti i tipi di file, ma solo immagini e mi sembra con alcuni limiti sulle dimensioni. Qui la documentazione => JetPack Photon.

WP Offload S3: esiste sia in versione free che PRO, al momento ho sempre usato la PRO e non so dirvi esattamente quali siano le limitazioni della versione gratuita, anche se la scelta di una PRO è dettata quando installo un software di terzi presso un cliente e voglio essere sicuro di avere una assistenza immediata. Il software prevedere anche una situazione mista, dove alcuni file possono essere locali e altri su Amazon S3. C’è la possibilità anche di spostare tutta la libreria multimediale in CDN con un solo comando e ci sono diverse opzioni di personalizzazione, poi sull’assistenza sono molto veloci e rispondono quasi immediatamente.

Configurazione di una CDN

Se volete risolvere il problema mettendo le mani al codice vi indico qui di seguito i passi che dovete eseguire, vi riporto quello che ho fatto sul sito che state leggendo, il quale funziona molto bene ma non posso assicurarvi che in altri siti ci siano delle condizioni che magari vanno aggiustate. Quindi eseguite questi passi usando sempre un’ambiente di prova.

Copia su S3: la prima operazione è quella di copiare tutta la vostra cartella uploads in un bucket di Amazon S3 rispettando la gerarchia delle directory. Quindi la prima cartella del bucket dovrà essere proprio la cartella uploads/. Questo vale sia per WordPress standard che multisite. Allego una schermata per farvi vedere come ho configurato il mio bucket su Amazon S3. Dopo la copia non cancellate i file della versione locale, lo facciamo dopo aver configurato un redirect.

Creazione distribuzione: in teoria questo passaggio è facoltativo, in quanto potremmo usare il bucket S3 direttamente come endpoint per le nostre immagini, però si perderebbero molte cose che il servizio di Amazon Cloudfront mette a disposizione. Per creare una nuova distribuzione su Cloudfront basta andare nella management console e eseguire i passi richiesti. Se volete sapere più in dettaglio l’aspetto di configurazione andate su Amazon Cloudfront per CDN.

Link alle immagini: Una volta che abbiamo copiato tutte le nostre risorse su Amazon S3 e abbiamo creato la distribuzione CDN dobbiamo configurare WP in modo che generi tutti i link della libreria media usando il dominio della CDN, come ad esempio content.dominio.com. Per fare questo dobbiamo cambiare i valori di due opzioni presenti nel database options.

upload_path = /uploads
upload_url_path = https://content.dominio.com/uploads

# Se utilizzate una versione di wordpress multisite
# dovete ripetere l'operazione per ogni sito configurato

upload_path = /uploads/sites/02
upload_url_path = https://content.dominio.com/uploads/sites/01

upload_path = /uploads/sites/03
upload_url_path = https://content.dominio.com/uploads/sites/03

Dopo questa modifica dovreste vedere sul sito la maggior parte delle immagini che puntano al nuovo link presente sulla CDN. Ho usato la parola maggior parte perché purtroppo nei post i link vengono generati durante la creazione del post e non in tempo reale quindi bisogna andare a modificare queste stringhe con un semplice comando SQL.

# Come per le opzioni di upload se usate una versione
# multisite eseguite il comando SQL per ogni file del sito

UPDATE wp_posts 
   SET post_content = REPLACE(post_content,
       'http://domino.attuale/wp-content/uploads/','https://cdn/uploads/')
 WHERE post_content LIKE '%http://domino.attuale/wp-content/uploads/%'

Se usate plugin particolari o personalizzazioni che cambiano altri valori dovete eseguire anche per questi la stessa tecnica e sostituire il dominio presente nel link. Ovviamente questo succede solo se stiamo usando un sito esistente, la configurazione di un nuovo sito è molto più semplice e non avremmo bisogno di fare queste operazioni di conversione.

Upload di nuove immagini

Anche se adesso possiamo visualizzare le immagini del sito utilizzando una CDN rimane il problema delle nuove immagini che devono essere caricate direttamente sul bucket S3 e non in locale. Per fare questo dobbiamo applicare un filtro alla funzione  upload_dir e installare il framework degli Amazon Web Services messo a disposizione dalla stessa Amazon.

Framework SDK PHP => Documentazione e download.

// Creazione di un client Amazon S3 per
// eseguire le funzioni presenti in SDK

$s3 = new Aws\S3\S3Client([
    'version' => 'latest',
    'region'  => 'sa-east-1'
]);

// Attivazione stream wrapper per mappare
// le funzioni di filesystem su Amazon S3

$s3->registerStreamWrapper();

// Notate che in questo caso dovete sempre usare endpoint
// del bucket S3 e non il dominio della distribuzione CDN

function my_upload_dir($path)
{
    $path['path' ]   = 's3://nome_bucket'.$path['path'];
    $path['basedir'] = 's3://nome_bucket'.$path['basedir'];

    return $path;
}

// Aggiungo filtro per aggiungere alla directory
// di upload il prefisso del bucket su Amazon S3

add_action('upload_dir','my_upload_dir');

Al momento vi ho indicato il codice necessario in modo che WordPress invece che scrivere sul file system locale scriva direttamente su Amazon S3, però sta a voi indicare questo codice in modo che venga eseguito solo quando necessario, ad esempio solo quando si caricano file dalla sezione Admin o quando vengono fatte operazioni AJAX particolari che eseguono un upload.

Cancellazione di una immagine

Anche per la funzione di cancellazione dobbiamo attivare un nuovo filtro, teoricamente non dovrebbe servire, però dato che WordPress esegue un controllo usando la funzione PHP di realpath() che non è compatibile con lo stream wrapper dobbiamo inserire un workaround.

function my_wp_delete_file($file)
{
    $bucket = 's3://nome_bucket';

    if (substr($file,0,strlen($bucket)) === $bucket)
       @unlink($file);

    return $file;
 }

// Dato che wordpress utilizza la funzione realpath che
// non funziona sullo stream wrapper anticipo la cancellazione

add_filter('wp_delete_file','my_wp_delete_file',10,1);

Terminata questa modifica non vi resta che provare a fare un nuovo upload, vedere se punta in modo corretto al dominio di CloudFront e poi provare a cancellarlo per controllare se i file di tutte le dimensioni intermedie vengano cancellati dal bucket di Amazon S3.

Cosa facciamo delle immagini locali?

A questo punto potremmo anche cancellare le immagini dal sistema locale se si vuole tenere il proprio server più snello. In ogni caso prima però consiglio di eseguire un redirect del vecchio link su quello nuovo in modo che il motore di ricerca non riceva una valanga di errori 404. Per eseguire questa operazione basta inserire una nuova regola su .htaccess.

# Correzione URL delle risorse multimediali dopo lo spostamento
# sul servizio di Content Delivery degli Amazon Web Services

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(wp-content/uploads/)(.*)$ https://cdn/uploads/$2 [R=301,L]

Se volete mantenere le vostre immagini in locale ed eseguire il redirect levate il primo comando indicato nell’esempio in modo da non controllare l’esistenza del file ed eseguire una redirect a prescindere se questa risorsa esista o non esista in locale.

WordPress in Cloud Computing

Guida completa su AWS

Questo articolo appartiene ad una serie di pubblicazioni che costituiscono una guida completa dedicata agli Amazon Web Services. Molti servizi che trattiamo in questo blog vengono anche spiegati con dei video che trovate nel nostro canale youtube. Se volete seguire questo percorso didattico iscrivetevi alla community Cloud AWS.

1 Commento

  1. Il plugin da te indicato è sicuramente ottimo, anche se secondo me ha un prezzo troppo elevato per grandi quantià di immagini e oltretutto il prezzo è annuale, quindi un costo perenne. Mi piace molto di più la soluzione fai da te con il framework PHP rilasciato da Amazon. IL lavoro da fare viene sicuramente ripagato.

condividi