WooCommerce su AWS

WooCommerce su AWS: come costruire un ecommerce scalabile e sicuro per i picchi di traffico

Hai un ecommerce WooCommerce che comincia a sentire il peso del successo. La pagina in homepage impiega cinque secondi a caricarsi, il checkout si interrompe durante i saldi, il server va in tilt quando arriva una campagna di marketing. WooCommerce resta una buona piattaforma, ma sopra una certa soglia di ordini serve un'infrastruttura pensata per reggere i picchi. Ecco l'architettura AWS che uso come riferimento, con le scelte di sicurezza che non sono opzionali.

WooCommerce nasce come plugin di WordPress e ne eredita la filosofia: un archivio di file PHP che legge e scrive su un database MySQL. Su un hosting condiviso funziona, su un singolo VPS funziona, ma la crescita è il momento in cui il modello tradizionale smette di reggere. La transazione di un checkout è uno script PHP che apre una connessione al database, scrive l'ordine, aggiorna lo stock, manda la mail e risponde all'utente. Su un catalogo con decine di migliaia di SKU e qualche centinaio di utenti in contemporanea, quel singolo processo diventa il collo di bottiglia di tutto il sistema.

AWS non risolve il collo di bottiglia con la bacchetta magica. Lo risolve con un cambio di mentalità architetturale: disaccoppiare lo stato, isolare i domini di guasto, replicare su più zone di disponibilità, spostare la cache il più vicino possibile all'utente. Tutto il resto è implementazione. Questo articolo descrive l'architettura di riferimento che ho usato su progetti reali, le ragioni di ogni scelta e le trappole che beccano anche i team esperti.

Il principio: stato separato, compute stateless

La prima decisione, quella da cui discendono tutte le altre, è trasformare il tier applicativo in stateless. Significa che nessun dato utente, nessun file caricato, nessuna sessione vive sulla macchina che esegue PHP. Tutto ciò che è dinamico va in un servizio condiviso a monte o a valle, mentre il compute diventa un bene fungibile che può essere aggiunto, rimosso e sostituito senza conseguenze.

Questa separazione è ciò che rende possibile il vero autoscaling. Senza stato locale, una nuova istanza EC2 entra nel pool e serve traffico esattamente come le altre. Senza stato locale, un deploy non è un momento di panico ma una rotazione controllata. Senza stato locale, un guasto al singolo server è invisibile all'utente finale perché la richiesta successiva atterra su un altro nodo.

WooCommerce, di per sé, non è stateless: scrive ordini, apre sessioni, carica immagini in wp-content/uploads. Il lavoro di architettura consiste nello spostare ciascuno di questi pezzi nel posto giusto. Le sezioni che seguono mostrano dove.

Architettura di rete: VPC Multi-AZ con tre livelli di subnet

Tutto comincia dalla VPC. Una Virtual Private Cloud ben progettata ha tre livelli di subnet, distribuiti su almeno due zone di disponibilità. Le zone di disponibilità sono data center fisicamente separati dentro la stessa regione AWS: una failure a livello di facility non deve mai essere visibile all'utente finale.

Il primo livello è fatto di subnet pubbliche, dove vivono solo il bilanciore di carico e i NAT Gateway. Sono le uniche risorse che possono parlare direttamente con Internet. Il secondo livello è fatto di subnet private applicative, dove girano le istanze EC2 o i container che eseguono PHP. Non hanno IP pubblico e non sono raggiungibili dall'esterno. Il terzo livello è fatto di subnet private dati, dove vivono Aurora, ElastiCache e i mount target di EFS. Completamente isolate da Internet, accettano connessioni solo dalle subnet applicative.

Architettura di un ecommerce WooCommerce in alta affidabilità su AWS
Architettura di un ecommerce WooCommerce in alta affidabilità su AWS: due Availability Zone, tre livelli di subnet, compute stateless, stato condiviso e un edge con CDN e WAF.

Questa segmentazione ha una contropartita importante: la VPC diventa il primo strato di difesa. Se le istanze applicative non hanno IP pubblico, nessuno può attaccarle direttamente. Il firewall è dato dai Security Groups, che regolano il traffico in modo strettamente unidirezionale: l'ALB accetta 443 da CloudFront, le EC2 accettano solo 443 dal Security Group dell'ALB, Aurora accetta 3306 solo dal Security Group delle EC2, EFS accetta 2049 solo dalle EC2. Ogni livello vede solo il precedente. È noioso da configurare ma è la base di tutto il resto.

Compute: EC2 Graviton, container o Fargate?

Sul tier applicativo ci sono tre strade, tutte valide, e la scelta dipende dal team più che dal carico di lavoro. Le confronto una a una.

La prima strada è EC2 con Auto Scaling Group, il modello tradizionale e più diffuso per WordPress e WooCommerce. Le istanze eseguono Linux, Nginx e PHP-FPM direttamente; il bilanciatore le aggiunge e le rimuove in base al carico. È semplice da capire, si integra nativamente con EFS via amazon-efs-utils e permette di ottimizzare PHP e OPcache con la granularità che si vuole. Il prezzo da pagare è la lentezza del bootstrap: una nuova istanza EC2 ci mette dai due ai cinque minuti tra boot, User Data e inizializzazione, che durante una vendita lampo è un'eternità.

La seconda strada sono i container su ECS o EKS. L'immagine Docker creata in staging è identica a quella che va in produzione; lo scaling è rapidissimo, perché un nuovo pod è pronto in secondi; la densità di carichi sullo stesso nodo è più alta. Il prezzo è la complessità operativa: serve un orchestratore, serve il driver EFS CSI, servono Access Point per gestire i permessi granulari su EFS. Ha senso se avete già un team DevOps strutturato e gestite più ambienti (sviluppo, staging, produzione) o più storefront WooCommerce in pipeline condivise. La scelta tra i due orchestatori, tra costi del control plane, Fargate e competenze richieste, è una decisione che merita un'analisi dedicata: la trovi in ECS o EKS, come scegliere l'orchestratore AWS senza pagare l'errore.

La terza strada è Fargate, dove AWS gestisce sia i nodi sia i container. È la via di mezzo: avete l'immutabilità di un container senza la complessità del cluster, ma pagate un sovrapprezzo del 40-60 per cento rispetto alle istanze EC2 equivalenti, perché Fargate non vi fa impaccare carichi diversi sulla stessa macchina. Per un ecommerce in produzione lo uso raramente: la spesa si vede in fattura e il guadagno in operatività non sempre compensa. Fargate Spot può ridurre la spesa, ma solo per task stateless e interrompibili: il confronto con EC2 va fatto sul carico reale, non sulla tariffa oraria isolata.

Sulle istanze vere, il tipo di processore conta. Le Graviton 3 (famiglia c7g o m7g) sono processori ARM che a parità di lavoro costano circa il 20 per cento in meno dei corrispondenti x86. PHP gira nativamente su ARM da anni, WooCommerce non ha dipendenze che lo impediscano, e il guadagno è immediato in fattura. Prima della migrazione, però, vanno verificati i plugin critici, soprattutto quelli di pagamento, cache e ottimizzazione delle immagini. Per carichi pesanti come il rendering del catalogo o la sincronizzazione degli ordini, la differenza si sente.

Lo scaling va governato con regole di Target Tracking, non solo sulla CPU ma soprattutto sul conteggio delle richieste per target dell'ALB (ALBRequestCountPerTarget): durante una campagna marketing, il numero di checkout in volo è un indicatore più rapido del carico medio del processore. Una soglia tipica è 1.200 richieste al minuto per istanza, ma va calibrata sul proprio carico.

Database: Aurora MySQL Multi-AZ e High Performance Order Storage

Il database è il pezzo più delicato. WooCommerce appoggiato a un MySQL tradizionale scala, ma in modo non lineare, e i punti dove rallenta sono ben noti: la tabella wp_posts che si gonfia di ordini scritti come custom post type, la wp_postmeta che esplode con i metadati di ogni variante di prodotto, i lock di scrittura che durante i saldi bloccano le letture del catalogo.

La prima scelta è Amazon Aurora MySQL, che separa il calcolo dallo storage e replica automaticamente i dati in sei copie su tre zone di disponibilità. Significa che un guasto al disco è gestito da Aurora stessa, senza intervento; significa che la latenza di replica è nell'ordine dei millisecondi, non dei secondi di una replica MySQL tradizionale. La configurazione minima è un'istanza writer per gli ordini e gli aggiornamenti di stock, e una o più Aurora Read Replicas per scalare le query di consultazione del catalogo.

La seconda scelta, da non rimandare, è WooCommerce High Performance Order Storage (HPOS). Introdotto di default da WooCommerce 8.2 e da completare per chi arriva da versioni precedenti, HPOS sposta gli ordini dalle tabelle wp_posts e wp_postmeta in quattro tabelle dedicate e indicizzate (_wc_orders, _wc_order_addresses, _wc_order_operational_data, _wc_orders_meta). Il risultato è che i checkout ad alto volume non contendono più con la lettura del catalogo per lo stesso lock sulla tabella principale. Su un ecommerce in crescita è la singola modifica che dà il ritorno più immediato.

Il terzo pezzo è AWS RDS Proxy, un bilanciere di connessioni che si mette tra il tier applicativo e Aurora. Senza, un autoscaling aggressivo porta ad aprire centinaia di connessioni MySQL in pochi secondi e il database restituisce il classico errore "Too many connections". RDS Proxy fa connection pooling e multiplexing: le istanze applicative si connettono a lui, lui tiene caldo un pool ridotto di connessioni verso Aurora. Il risultato è un database che regge picchi di cinque o dieci volte superiori senza cambiare taglia.

Storage: EFS per i media, S3 per gli oggetti statici

Il file system condiviso è Amazon EFS, montato da tutte le istanze applicative sulla cartella wp-content/uploads. EFS è accessibile da più zone di disponibilità, scala senza intervento ed elimina il problema classico del "dove sono i media" quando un autoscaling group ricrea le istanze. La configurazione raccomandata è Elastic Throughput, che adatta la banda al carico, e EFS Intelligent-Tiering, che sposta automaticamente i file non letti da oltre trenta giorni nella classe Infrequent Access con un risparmio fino al 92 per cento sullo storage.

Per le immagini di prodotto, le risorse statiche e i file scaricabili, conviene spostarsi su Amazon S3 con un plugin WordPress che redirige gli URL dei media al bucket. CloudFront distribuisce S3 come origine, EFS resta solo per i file che WooCommerce scrive a caldo durante l'editing. È un passaggio non banale, perché richiede di riconfigurare tutti i percorsi degli allegati esistenti, ma una volta fatto libera EFS dal peso delle immagini storiche e lo lascia libero di servire i caricamenti recenti a bassa latenza.

Cache: ElastiCache Redis per oggetti e sessioni

Senza cache, una pagina di WooCommerce che mostra un singolo prodotto può eseguire oltre cento query MySQL: opzioni, transitori, metadati, tassonomie, ordini correlati, articoli in evidenza. Il database regge per un po', poi diventa il collo di bottiglia che nessuno aveva previsto.

ElastiCache for Redis risolve il problema in due modi. Il primo è il persistent object cache: installando il drop-in object-cache.php nel wp-content, WordPress sposta in RAM la cache di opzioni, transitori e risultati di query ricorrenti. Su una pagina di prodotto il numero di query al database scende da oltre cento a meno di dieci.

Il secondo è la persistenza delle sessioni PHP. Senza un gestore esterno, le sessioni vivono nel filesystem locale delle istanze EC2: il carrello di un utente che atterra su un nodo diverso durante uno scale-in si perde, con la conversione in fumo. Impostando session.save_handler = redis, ogni carrello è in Redis e segue l'utente indipendentemente dal nodo che serve la richiesta.

Edge: CloudFront e la cache selettiva

Amazon CloudFront è la CDN globale davanti a tutto: serve gli asset statici dalle edge location, termina la connessione SSL/TLS con un certificato gestito da AWS Certificate Manager e nasconde gli IP pubblici dell'ALB, che è una forma di difesa non da poco contro gli scanner automatici che cercano bilanciatori esposti.

Il punto critico è la cache delle pagine HTML. Su un ecommerce WooCommerce non si può applicare una cache aggressiva su tutto: carrello, checkout, area personale e back office devono sempre andare all'origine. La tecnica corretta è la cookie whitelisting: CloudFront inoltra al server di origine solo i cookie essenziali di WooCommerce (woocommerce_items_in_cart, woocommerce_cart_hash, wp_woocommerce_session_*). La pagina del catalogo viene servita dalla cache all'utente anonimo, perché quei cookie sono assenti; appena il cookie del carrello compare, CloudFront scavalca la cache e parla con l'origine. Il risultato è un tasso di cache hit elevato sulle pagine pubbliche senza rompere i flussi transazionali.

Sicurezza in profondità

Su un ecommerce WooCommerce la sicurezza non è una casella da spuntare, è una proprietà emergente del sistema. Le ho organizzate in sette livelli che vale la pena elencare uno per uno.

Flusso di una richiesta verso un ecommerce WooCommerce su AWS e i sette livelli di difesa
Flusso di una richiesta verso un ecommerce WooCommerce su AWS: CloudFront, WAF, ALB, compute, Aurora. Sotto, i sette livelli di difesa che vanno applicati contemporaneamente.

Il primo livello è la cifratura in transito: TLS 1.3 su tutta la catena, certificati gestiti da AWS Certificate Manager, forzare HTTPS con il redirect redirect-to-https su CloudFront. In WooCommerce, FORCE_SSL_ADMIN e l'header HTTP_X_FORWARDED_PROTO servono a evitare loop di reindirizzamento e a forzare HTTPS anche sul back office.

Il secondo livello è la mitigazione DDoS. CloudFront con AWS Shield Standard protegge gli attacchi più comuni a costo zero. Se l'ecommerce vive di campagne marketing aggressive o è un bersaglio noto, AWS Shield Advanced aggiunge un servizio di risposta 24/7 del DDoS Response Team di AWS, una garanzia di spesa in caso di attacco e protezione per ALB, Elastic IP e Route 53.

Il terzo livello è il filtraggio applicativo con AWS WAF. Le managed rules di AWS coprono SQL injection, XSS, user agent malevoli e bot noti; si aggiungono regole di rate limit per IP (per esempio 2.000 richieste in 5 minuti) per mitigare scraping e credential stuffing. Le regole vanno riviste almeno ogni trimestre, perché i pattern di attacco cambiano.

Il quarto livello è la segmentazione di rete, già vista nella sezione sull'architettura. Le istanze applicative non hanno IP pubblico, il database non accetta connessioni se non dal Security Group delle EC2, EFS è accessibile solo dalle subnet applicative. È una difesa banale ma continua a essere la più efficace.

Il quinto livello è la gestione dei segreti. Le credenziali del database, le chiavi dei gateway di pagamento e i token delle API terze vanno in AWS Secrets Manager, recuperate al boot da un ruolo IAM con permessi stretti al solo ARN del segreto. Un'IAM policy scritta bene dice secretsmanager:GetSecretValue su arn:aws:secretsmanager:...:secret:woo-db-prod e nient'altro.

Il sesto livello è la cifratura at rest: KMS abilitato su Aurora, EBS, EFS e S3; su ElastiCache for Redis la cifratura at rest va attivata esplicitamente e verificata con un benchmark, perché può incidere sulle prestazioni. Su Aurora, il flag è --storage-encrypted alla creazione del cluster, senza il quale il database riparte in chiaro. Su Redis, la cifratura at rest va attivata alla creazione e verificata con un benchmark. Su EFS, la cifratura è nativa al file system, ma va esplicitata in fase di creazione; una policy di AWS Config può notificare se viene creato un file system senza cifratura.

Il settimo livello è il monitoraggio continuo: AWS GuardDuty analizza i log di CloudTrail, VPC Flow Logs e DNS per individuare comportamenti anomali (mining di credenziali, esfiltrazione, accessi da IP insoliti); AWS Config valuta le risorse contro regole di compliance desiderate e notifica le deviazioni; CloudTrail conserva l'audit delle API calls, consultabile per indagini successive. Sono servizi che lavorano in silenzio finché non trovano qualcosa, e a quel punto sono la differenza tra un incidente gestito e un incidente in cronaca.

Un'ultima nota sulla conformità PCI-DSS. WooCommerce non memorizza di per sé i dati della carta di credito se i pagamenti sono gestiti da gateway esterni come Stripe, Adyen o Nexi, che redirezionano l'utente sulle proprie pagine tokenizzate. In questo caso il merchant non tratta PAN, e il perimetro PCI si restringe di molto. Quando invece si integra un gateway che restituisce i dati al sito (form custom, salvataggio carta per acquisti ricorrenti), il perimetro include il server applicativo e occorre una valutazione formale. AWS aiuta: è un provider PCI-DSS Level 1, e documenta i controlli condivisi. La responsabilità della compliance, però, resta del merchant, e l'architettura va verificata contro i requisiti specifici del proprio QSA.

Disaster recovery e osservabilità

L'alta affidabilità non è solo "non cade mai", è anche "quando qualcosa si rompe, ci si rialza in fretta". Su Aurora, la replica Multi-AZ e i backup automatici con Point-in-Time Recovery danno una base per un RPO nell'ordine dei minuti. Il failover automatico del writer può avere un RTO nell'ordine dei secondi, ma va misurato sul cluster reale e non promesso a priori. Il runbook deve indicare chi promuove la replica, come si verifica il DNS del nuovo writer e come si riaprono le connessioni tramite RDS Proxy. Almeno una volta a trimestre va eseguito un test controllato, registrando tempi, errori applicativi e dati eventualmente persi. Su EFS, il backup automatico e la possibilità di ripristinare uno stato precedente proteggono dai cancellamenti accidentali. Su S3, il versioning è una riga di configurazione che evita discussioni nei momenti peggiori.

L'osservabilità si costruisce a tre livelli. Sulle metriche di infrastruttura (CPU, memoria, latenza ALB, connessioni RDS, throughput EFS) gli allarmi CloudWatch sono la base. Sulle metriche applicative, un plugin come Query Monitor permette di identificare le query lente in sviluppo e staging prima che arrivino in produzione. Sui log applicativi, l'invio a CloudWatch Logs con filtri per livello e per parola chiave rende visibili gli errori senza dover entrare in ogni istanza via SSH.

Costi: la lista nascosta

Parlare di costi prima di partire è utile, perché WooCommerce su AWS non è economico come sembra. Le voci che pesano, in ordine.

Il compute domina. Le istanze Graviton 3 sono circa il 20 per cento più economiche delle equivalenti x86 e sono raccomandate; le istanze Spot possono abbattere il costo fino al 70 per cento ma sono interrompibili, quindi vanno usate solo dove il carico è stateless e tollera il riavvio. Per i carichi di produzione, On-Demand o Reserved Instances (per ambienti stabili) sono la base.

Aurora si paga per ACU (Aurora Capacity Unit) e per storage consumato; la replica Multi-AZ raddoppia il costo del cluster, ma è il prezzo dell'alta affidabilità. RDS Proxy ha un costo per ACU che va considerato; RDS Proxy è uno di quei servizi che si ripaga da solo in affidabilità durante i picchi.

ElastiCache si paga per nodo, e un cluster Redis con replica Multi-AZ costa quanto un'istanza media. EFS si paga per GB e per throughput: Elastic Throughput evita brutte sorprese, ma Intelligent-Tiering sui file non recenti riduce il costo del 92 per cento, una riduzione che su un catalogo con anni di immagini è significativa.

CloudFront si paga per traffico in uscita, e su un ecommerce che serve molte immagini di prodotto è una voce che può superare il costo del compute. La soluzione è tenere CloudFront davanti a S3 per tutti i media statici (l'origine S3 ha un costo di uscita inferiore) e configurare le origini multiple per separare i flussi.

Per avere un ordine di grandezza, questa è una stima mensile indicativa in euro, senza IVA, costi di sviluppo, domini e imposte. Assume eu-south-1, due AZ, prezzi On-Demand, traffico cacheabile e nessun Shield Advanced: il prezzo reale va verificato con AWS Pricing Calculator.

Due profili di costo mensile indicativo
Voce5.000 SKU · 50.000 visite50.000 SKU · 500.000 visite
Compute e bilanciamento€150–250€500–900
Aurora, Proxy e Redis€180–300€650–1.100
EFS, S3, CloudFront e WAF€80–180€300–700
Totale orientativo€410–730€1.450–2.700

Il totale non è un preventivo: backup, log, trasferimento dati e picchi possono spostarlo sensibilmente. La tabella serve a rendere esplicita la soglia economica prima di scegliere questa architettura.

Il WAF costa per regola e per milione di richieste ispezionate. Le managed rules di base hanno un costo fisso, che va messo a budget insieme ai costi ricorrenti. AWS Shield Advanced costa circa 3.000 dollari al mese: è una spesa significativa, ma è assicurazione, non costo operativo, e va valutata contro il rischio di un incidente che blocchi le vendite.

Quando partire e quando fermarsi

Questa architettura non è per ogni ecommerce. È la risposta corretta a partire da una certa soglia: catalogo con migliaia di SKU, traffico nell'ordine delle centinaia di utenti in contemporanea nei picchi, obblighi di compliance (anche solo GDPR in modo serio), campagne di marketing che portano a picchi del 5-10x del traffico medio. Sotto quella soglia, un hosting gestito WooCommerce di qualità costa meno e dà meno grattacapi operativi.

Il punto di rottura è quando il tempo che il team passa a gestire l'infrastruttura supera il tempo che passa a migliorare il prodotto. A quel punto l'architettura AWS non è un costo, è un investimento in concentrazione.

Se state valutando questa scelta per un progetto reale, scrivete in due righe cosa avete oggi e cosa vi aspettate nei prossimi dodici mesi: la prima decisione da prendere è capire se la complessità che introduce AWS è giustificata dai numeri del vostro business. Spesso non lo è. Quando lo è, vale la pena farla bene.

Fonti

Easter egg

Il sette più frequente nelle architetture WooCommerce su AWS non è un numero magico, è il numero di livelli di difesa che si dimenticano uno a uno. Il primo a cadere è quasi sempre il backup non ripristinato.