Se stai leggendo questa guida, probabilmente hai già provato a installare Drupal 11 su un hosting condiviso e hai avuto problemi. Oppure hai seguito il tutorial ufficiale di Drupal e ti sei scontrato con un muro.Nessun problema: questa guida ti spiegherà perché c'è un problema tecnico di fondo e come risolverlo in modo semplice e definitivo (Guida realizzata per Drupal 11 Core e non per Drupal cms ex Starshot).🤔 Il problema di base: perché la struttura standard di Drupal NON funziona su molti hosting condivisi?Partiamo dall'inizio. Drupal 11, quando viene installato con Composer (il gestore di pacchetti PHP ufficiale), crea una struttura di cartelle come questa:progetto-drupal/
├── composer.json
├── composer.lock
├── vendor/ ← tutte le librerie PHP (Symfony, Twig, ecc.)
└── web/ ← la ROOT pubblica (document root)
├── index.php
├── core/
├── modules/
├── themes/
└── sites/Questa struttura è perfetta dal punto di vista della sicurezza perché tutto il codice PHP sensibile (le librerie in vendor/, le configurazioni, ecc.) si trova fuori dalla cartella accessibile al web. Solo la cartella web/ è esposta pubblicamente.Per far funzionare questa struttura, l'hosting deve permetterti di impostare la document root (la cartella che il server web mostra ai visitatori) su web/. In pratica, devi poter dire ad Apache/Nginx: "quando qualcuno visita il mio sito, mostra i file che stanno dentro la cartella web/, non quelli nella cartella principale".🚫 Il problema sugli hosting condivisiLa maggior parte degli hosting condivisi NON ti permette di cambiare la document root. La document root è fissa e bloccata su public_html/ (o httpdocs/ o www/). Non puoi modificarla. Punto.Ma c'è anche un secondo problema, ancora più subdolo: la direttiva open_basedir.🔒 Cos'è open_basedir?È una direttiva di sicurezza di PHP che limita i file che PHP può aprire a una specifica cartella e alle sue sottocartelle. Su molti hosting condivisi, open_basedir è impostata proprio su public_html/. Questo significa che PHP non può "vedere" né accedere a file che stanno fuori da public_html/.Facciamo un esempio concreto. Se provassi a installare Drupal con la struttura standard su un hosting condiviso:public_html/ ← document root fissa (open_basedir punta qui)
├── web/ ← qui dentro ci sono index.php, core, modules...
│ └── ...
vendor/ ← FUORI da public_html! PHP non può accederci!Il risultato? PHP non riesce a caricare le librerie in vendor/ perché si trovano fuori dai limiti imposti da open_basedir. Drupal non si avvia nemmeno, o dà errori inspiegabili.Morale: sugli hosting condivisi, tutto il codice deve stare dentro public_html/. Non puoi avere nulla fuori. Ecco perché serve la struttura FLAT.📜 Un po' di storia: come si installava Drupal "una volta"?Prima dell'avvento di Composer (che è diventato lo standard ufficiale da Drupal 8 in poi), Drupal si installava in modo molto più semplice: scaricavi un pacchetto .zip o .tar.gz dal sito ufficiale, lo decomprimevi direttamente in public_html/, e il gioco era fatto.Quelle si chiamano installazioni "legacy" (o "tradizionali"). Funzionavano così:public_html/ ← tutto dentro qui
├── index.php
├── core/
├── modules/
├── themes/
├── sites/
├── vendor/ ← già incluso nel pacchetto
└── ...Semplice, no? Nessun problema con open_basedir, nessuna storia di document root. E funzionava perfettamente.Ma c'era un problema enorme: la gestione delle dipendenze. Drupal moderno usa decine di librerie PHP esterne (Symfony, Guzzle, Twig, Psr, ecc.). Nel pacchetto scaricabile, queste librerie erano già incluse nella cartella vendor/. Ma come si aggiornavano? Come si gestivano le versioni? Era un caos. Spesso le installazioni legacy finivano con versioni mixate, librerie mancanti o in conflitto.Per questo motivo, dal 2018 circa, il team di Drupal ha abbandonato ufficialmente le installazioni "legacy" con pacchetto scaricabile. Oggi l'unico metodo supportato è Composer.📌 Nota storica: Ancora oggi trovi in giro vecchi tutorial che ti dicono di scaricare un file .zip da drupal.org. Ignorali. Per Drupal 10 e 11, quel metodo non è più supportato e può dare problemi di sicurezza e compatibilità.Ma Composer crea la struttura con web/... e noi non possiamo usarla sugli hosting condivisi. Sembra un paradosso, vero? Fortunatamente esiste una soluzione geniale: il plugin Scaffold.✨ Cos'è il plugin Scaffold di Drupal (e perché è rivoluzionario)Gli sviluppatori di Drupal erano ben consapevoli del problema degli hosting condivisi. Per questo hanno creato un plugin Composer chiamato drupal/scaffold.🔧 Cos'è Scaffold?Scaffold (in inglese "impalcatura") è un plugin che permette a Composer di copiare i file pubblici (index.php, .htaccess, robots.txt, ecc.) dove vuoi tu, non necessariamente dentro web/.Quando lanci composer create-project per installare Drupal, Scaffold viene eseguito automaticamente e copia i file "scaffold" nella cartella che tu gli indichi. Di default, li copia in web/. Ma grazie a Scaffold, puoi decidere tu la cartella di destinazione, modificando il file composer.json.In poche parole, Scaffold disaccoppia la posizione dei file pubblici dal resto del progetto. Questo significa che possiamo dire a Scaffold: "copia index.php, .htaccess e tutti i file pubblici direttamente nella root del progetto, non dentro web/".Ed è esattamente quello che faremo in questa guida: useremo Scaffold per generare una struttura FLAT, dove tutto (inclusi i file pubblici) sta dentro public_html/, risolvendo così i problemi di document root fissa e open_basedir.Il bello è che manteniamo tutti i vantaggi di Composer: composer.json, composer.lock, aggiornamenti sicuri, gestione perfetta delle dipendenze. Il meglio di entrambi i mondi.🔧 Cosa significa "struttura FLAT"?La struttura FLAT è semplicemente l'installazione di Drupal in cui non esiste la cartella web/. Tutto è nella stessa cartella root.Struttura standard (NON funziona su hosting condivisi):public_html/
└── web/
├── core/
├── modules/
├── themes/
├── vendor/
└── index.phpStruttura FLAT (funziona su hosting condivisi):public_html/
├── core/
├── modules/
├── themes/
├── vendor/
├── index.php
├── .htaccess
├── composer.json
├── composer.lock
└── sites/
└── default/
└── files/In pratica, prendiamo tutto ciò che starebbe dentro web/ e lo "spostiamo su" di un livello, eliminando la cartella intermedia.Questa struttura risolve entrambi i problemi:✅ La document root può rimanere public_html/ (nessun problema con hosting che non permettono di cambiarla)✅ Tutto il codice (compreso vendor/) sta dentro public_html/, quindi open_basedir non blocca nulla✅ Manteniamo Composer e il plugin Scaffold per la gestione dei file pubblici📋 RequisitiAccesso SSH al tuo hostingComposer installato (la maggior parte degli hosting lo ha, altrimenti chiedi al supporto)Dominio puntato alla cartella public_html/PHP 8.1 o superiore🧭 GUIDA PASSO PASSO1️⃣ Prepara l'ambienteCollegati via SSH e vai nella cartella del dominio:📋 Copiacd ~/domains/tuodominio.itElimina eventuali installazioni precedenti (per partire da zero):📋 Copiarm -rf public_html
rm -rf drupal11tmpCrea una nuova public_html vuota:📋 Copiamkdir public_html2️⃣ Installa Drupal in una cartella temporaneaUsiamo una cartella temporanea per preparare l'installazione senza toccare ancora public_html/:📋 Copiacomposer create-project drupal/recommended-project:^11 drupal11tmpQuesto comando crea la cartella drupal11tmp/ con dentro la struttura standard (inclusa web/).3️⃣ Entra nella cartella temporanea📋 Copiacd drupal11tmp4️⃣ Trasforma in struttura FLATOra spostiamo tutto il contenuto di web/ nella root del progetto temporaneo:📋 Copiamv web/* web/.* . 2>/dev/null
rmdir webOra la cartella drupal11tmp/ contiene core/, modules/, index.php, ecc. direttamente nella root.5️⃣ Modifica il file composer.jsonDobbiamo dire a Composer e a Scaffold che la nuova root pubblica è la cartella corrente (non più web/). Apri composer.json e modifica la sezione extra.drupal-scaffold.locations:📋 Copia esempio{
"extra": {
"drupal-scaffold": {
"locations": {
"web-root": "./"
}
}
}
}Poi rigenera i file di Drupal con Scaffold:📋 Copiacomposer drupal:scaffold
composer dump-autoload6️⃣ Copia tutto in public_htmlOra copiamo l'intera installazione (con struttura FLAT già pronta) dentro public_html/:📋 Copiacp -R * ~/domains/tuodominio.it/public_html
cp -R .* ~/domains/tuodominio.it/public_html 2>/dev/null7️⃣ Crea la cartella files per i file caricati📋 Copiamkdir -p ~/domains/tuodominio.it/public_html/sites/default/files
chmod 775 ~/domains/tuodominio.it/public_html/sites/default/files8️⃣ Elimina la cartella temporanea (non serve più)📋 Copiacd ..
rm -rf drupal11tmp9️⃣ Sistema composer.lockEntra in public_html/ e aggiorna il lock file per sicurezza:📋 Copiacd ~/domains/tuodominio.it/public_html
composer update --lock🔟 Installa Drupal dal browserApri il tuo dominio:📋 Copiahttps://tuodominio.itSegui la procedura guidata di installazione di Drupal. Inserisci i dati del database, configura il sito e il gioco è fatto!⚠️ Problema comune dopo l'installazione: interfaccia admin "monca"Su alcuni hosting condivisi, dopo l'installazione potrebbe capitare che:la toolbar di amministrazione sia ridotta o incompletamancano voci di menul'interfaccia sembri "tagliata" o non funzioni correttamenteCausa: un file .htaccess generato da Drupal in sites/default/files/ che usa direttive Apache (Options) non sempre permesse sugli hosting condivisi. Apache non dà errore 500, ma impedisce a Drupal di funzionare correttamente.✅ SoluzioneApri il file:📋 Copiapublic_html/sites/default/files/.htaccessTrova questa riga:📋 CopiaOptions -Indexes -ExecCGI -Includes -MultiViewsCommentala così (basta mettere il cancelletto all'inizio):📋 Copia#Options -Indexes -ExecCGI -Includes -MultiViewsSalva il file e ricostruisci la cache di Drupal:📋 Copiacd ~/domains/tuodominio.it/public_html
php core/scripts/drupal cache:rebuildOppure vai su /admin/config/development/performance e clicca "Svuota tutte le cache".L'interfaccia tornerà immediatamente normale.📌 Nota: alcuni aggiornamenti di Drupal (eseguibili con composer update) possono rigenerare il file .htaccess nella cartella files/. Se il problema dovesse ripresentarsi, ripeti semplicemente la modifica.🚫 Perché evitare gli installer automatici (tipo "installazione in 1 click")⚠️ ATTENZIONE: Molti hosting offrono pulsanti magici del tipo "Installa Drupal in 1 click". Sembra comodo, ma è una trappola. Ecco perché.❌ I problemi delle installazioni automaticheNessuna gestione delle dipendenze: Drupal oggi è fatto di decine di librerie PHP (Symfony, Guzzle, Twig...). Un installer automatico te le dà "impacchettate" alla meglio, senza un vero sistema di aggiornamento.Il file composer.lock non esiste o è incompleto: Questo è il punto fondamentale. composer.lock è il file che congela esattamente la versione di OGNI singola libreria e modulo installato. Senza di esso, non sai mai cosa c'è realmente nel tuo sito.Nessuna mappatura delle versioni: Con Composer, ogni pacchetto ha una versione precisa (es. symfony/http-foundation: v6.4.0). Con un installer automatico, hai una "zuppa" di file senza un vero controllo di versione.Aggiornamenti un disastro: Prova ad aggiornare Drupal installato con un installer automatico. Molto probabilmente si rompe tutto perché mancano le informazioni su quali versioni esatte delle dipendenze erano presenti.Non puoi aggiungere moduli via Composer: Il comando composer require drupal/nome_modulo è il modo standard per aggiungere moduli. Con un installer automatico, o non funziona o crea conflitti.Struttura fragile: Questi installer spesso modificano i percorsi, spostano file, creano configurazioni anomale. Funzionano "oggi", ma domani? Nessuna garanzia.📊 Il cuore del problema: composer.lock e la mappatura delle dipendenzeQuando installi Drupal con Composer, vengono generati DUE file fondamentali:composer.json → cosa vuoi (es. "drupal/core": "^11")
composer.lock → cosa hai ESATTAMENTE (es. "drupal/core": "11.0.3",
"symfony/http-foundation": "6.4.0",
"twig/twig": "3.8.0", ...)composer.lock è un file che elenca OGNI singolo pacchetto con la sua versione precisa, il suo hash di integrità, le sue dipendenze e sottodipendenze. È come la "mappa catastale" del tuo progetto. Senza di essa, stai navigando alla cieca.Con un installer automatico, tipicamente:❌ composer.lock è assente❌ Oppure è un file falso, generato a mano❌ La cartella vendor/ è un ammasso di file senza tracciabilità❌ Non sai quali versioni di Symfony, Twig, Guzzle ecc. stai usando✅ Con Composer (questa guida)composer.json + composer.lock presenti e realiOgni pacchetto ha versione precisaMappatura completa di TUTTE le dipendenzeAggiornamenti sicuri: composer updateModuli aggiungibili con un comandoPuoi ricostruire l'intero progetto da zeroCompatibile con hosting condivisiSviluppo professionale❌ Con installer automaticocomposer.lock assente o fasulloVersioni delle librerie? MisteroNessuna mappatura delle dipendenzeAggiornare = rischio altissimoModuli via FTP come nel 2005Non puoi replicare l'installazioneSpesso dà problemi con hostingSolo hobbistica amatoriale🎯 Cosa fare se hai già usato un installer automatico?Se hai già installato Drupal con un "1-click installer", hai due opzioni:Butta via tutto e reinstalla con questa guida (soluzione consigliata, ci metti 15 minuti e hai un sito professionale, aggiornabile e sicuro).Converti manualmente (procedura complessa: devi ricostruire composer.json, generare un vero composer.lock, riorganizzare le cartelle... sconsigliato).Il mio consiglio: esporta i contenuti (se ne hai già creati), cancella l'installazione automatica e segui questa guida da zero. Ne guadagni in sanità mentale, sicurezza e futuro.💡 Nota bene: Gli installer automatici nascondono sempre la complessità. Ma Drupal è un CMS professionale che richiede una gestione professionale delle dipendenze. Composer non è un optional, è lo standard ufficiale da anni. Usalo.🎯 Conclusione✅ Hai ora:Drupal 11 installato con ComposerStruttura FLAT (nessuna cartella web/)Compatibile con hosting condivisi (document root fissa + open_basedir)composer.json e composer.lock reali e funzionantiMappatura completa di TUTTE le dipendenzeAggiornabile con un semplice composer updateModuli installabili via composer requireSicuro, stabile e professionale🖱️ Consiglio: i comandi sono copiabili con un click sul pulsante "Copia" in ogni riquadro grigio.Guida basata sull'esperienza reale di installazione su hosting condiviso del Provider Host.it
document.querySelectorAll('.copy-btn').forEach(button => {
button.addEventListener('click', function() {
const codeToCopy = this.getAttribute('data-code');
const textarea = document.createElement('textarea');
textarea.value = codeToCopy;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
const originalText = this.innerHTML;
this.innerHTML = '✅ Copiato!';
this.classList.add('copied');
setTimeout(() => {
this.innerHTML = originalText;
this.classList.remove('copied');
}, 2000);
});
});