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 PASSO
.guida-drupal pre {
background-color: #2d3139 !important;
color: #f8f8f2 !important;
padding: 15px !important;
border-radius: 6px !important;
border: 1px solid #3e4451 !important;
overflow-x: auto !important;
font-family: 'Courier New', Courier, monospace !important;
font-size: 14px !important;
line-height: 1.5 !important;
margin: 15px 0 !important;
}
.guida-drupal code {
font-family: 'Courier New', Courier, monospace !important;
color: #e06c75 !important;
background-color: #f5f5f5 !important;
padding: 2px 6px !important;
border-radius: 4px !important;
font-size: 90 !important;
}
.guida-drupal pre code {
color: #f8f8f2 !important;
background-color: transparent !important;
padding: 0 !important;
border-radius: 0 !important;
font-size: 100% !important;
}
.guida-drupal .code-title {
font-weight: bold !important;
color: #4b5263 !important;
font-size: 14px !important;
}
.guida-drupal .code-block {
margin-top: 15px !important;
margin-bottom: 15px !important;
}
1️⃣ Prepara l'ambiente e ripulisci public_htmlPer eseguire questa guida è fundamental avere un hosting con accesso SSHPrima di iniziare, dobbiamo assicurarci che la cartella del tuo sito sia completamente vuota. Molti hosting non permettono di cancellare direttamente la cartella public_html perché è una directory di sistema. Pertanto, andremo a svuotare solo il suo contenuto.Puoi farlo in due modi:Via File Manager: Accedi al pannello del tuo hosting, entra in public_html, attiva l'opzione "Mostra file nascosti" nelle impostazioni, seleziona tutto e cancella.Via SSH (Consigliato): Collegati al terminale ed esegui questi comandi per ripulire tutto ed eliminare eventuali residui di vecchie installazioni nella cartella temporanea:📋 Copia via SSHcd ~/domains/tuodominio.it/public_html
rm -rf *
rm -rf .[^.]* 2>/dev/null
cd ..
rm -rf drupal11tmpNota: Il comando finale di rimozione di drupal11tmp serve come rete di sicurezza nel caso tu stia ripetendo la procedura da zero, evitando conflitti con vecchi tentativi falliti.IMPORTANTE: sostituisci in tutta la guida "tuodominio.it" con il sito reale ad esempio "test26.sviluppo.host"2️⃣ Installa Drupal nella Sandbox TemporaneaCreiamo il progetto scaricando i file in una cartella temporanea isolata dal browser. Questo evita interferenze con le cache del server o configurazioni aggressive dell'hosting durante la fase iniziale:📋 Copia via SSHcomposer create-project drupal/recommended-project drupal11tmp --no-installPerché usiamo il parametro --no-install? Questo flag dice a Composer di scaricare solo la struttura iniziale dei file di configurazione base, senza avviare subito il download dei pacchetti effettivi del core. In questo modo, congeliamo l'installazione per avere il tempo di modificare i percorsi nel file composer.json nei passaggi successivi. Solo così Composer saprà fin dal primo secondo che si tratta di una struttura FLAT, evitando di generare cartelle errate che poi risulterebbero impossibili da spostare in modo pulito.3️⃣ Entra nella cartella temporaneaSpostati all'interno della directory appena creata per iniziare le modifiche strutturali:📋 Copia via SSHcd drupal11tmp4️⃣ Sposta i file per la struttura FLATSpostiamo tutto il contenuto della cartella web/ direttamente nella radice temporanea principale ed eliminiamo la cartella web/ ormai vuota:📋 Copia via SSHcp -R web/* .
cp -R web/.[^.]* . 2>/dev/null
rm -rf web🔍 Nota di trasparenza (Cosa sta succedendo?): Se dopo aver eseguito questo comando controlli la cartella tramite il File Manager dell'hosting, noterai che sono presenti solo tre file: composer.json, composer.lock e LICENSE.txt. È del tutto normale!Poiché al Punto 2 abbiamo usato il comando --no-install, Composer ha scaricato solo il modello di base (template). In questa fase iniziale, la cartella web/ non conteneva ancora i file veri e propri di Drupal (come la cartella core/, index.php, moduli o temi), ma ospitava solo pochissimi file di configurazione nascosti. Con questo passaggio abbiamo spostato quei pochi elementi e rimosso la cartella web/ per preparare il terreno. I veri file di Drupal compariranno solo tra poco, quando lanceremo l'installazione effettiva.5️⃣ Modifica il file composer.jsonApri il file composer.json presente nella cartella temporanea e configuralo per la struttura FLAT. Devi impostare la web-root su ./ e rimuovere il prefisso web/ da tutte le voci presenti in installer-paths, blindando anche l'endpoint dei pacchetti. Il file deve apparire esattamente così:📋 Struttura corretta del file composer.json{
"name": "drupal/recommended-project",
"type": "project",
"repositories": {
"drupal": {
"type": "composer",
"url": "https://drupal.org"
}
},
"require": {
"composer/installers": "^2.3",
"drupal/core-composer-scaffold": "^11.4",
"drupal/core-recipe-unpack": "^11.4",
"drupal/core-project-message": "^11.4",
"drupal/core-recommended": "^11.4"
},
"config": {
"allow-plugins": {
"composer/installers": true,
"drupal/core-composer-scaffold": true,
"drupal/core-recipe-unpack": true,
"drupal/core-project-message": true
}
},
"extra": {
"drupal-scaffold": {
"locations": {
"web-root": "./"
}
},
"installer-paths": {
"core": ["type:drupal-core"],
"libraries/{$name}": ["type:drupal-library"],
"modules/contrib/{$name}": ["type:drupal-module"],
"profiles/contrib/{$name}": ["type:drupal-profile"],
"themes/contrib/{$name}": ["type:drupal-theme"],
"drush/Commands/contrib/{$name}": ["type:drupal-drush"],
"modules/custom/{$name}": ["type:drupal-custom-module"],
"profiles/custom/{$name}": ["type:drupal-custom-profile"],
"themes/custom/{$name}": ["type:drupal-custom-theme"],
"recipes/{$name}": ["type:drupal-recipe"]
}
}
}6️⃣ Abilita i plugin ed esegui lo Scaffold nella SandboxAutorizziamo il plugin dello Scaffold, avviamo l'installazione completa scaricando tutti i pacchetti del Core all'interno della sandbox temporanea e infine rigeneriamo l'autoloader:📋 Copia via SSHcomposer config allow-plugins.drupal/core-composer-scaffold true
composer drupal:scaffold
composer install
composer dump-autoload7️⃣ Copia l'installazione FLAT pronta dentro public_htmlOra che l'installazione FLAT è pronta nella sandbox, completa di file vitali generati (come index.php e .htaccess) e della cartella vendor/, copiamo in sicurezza tutto il blocco nella directory pubblica finale del dominio:📋 Copia via SSHcp -R * ../public_html/
cp -R .[^.]* ../public_html/ 2>/dev/null8️⃣ Crea la cartella files per i mediaGeneriamo la directory in cui Drupal gestirà le immagini e i caricamenti pubblici degli utenti, assegnandole i permessi di scrittura adatti all'ambiente condiviso:📋 Copia via SSHmkdir -p ../public_html/sites/default/files
chmod 775 ../public_html/sites/default/files9️⃣ Elimina la cartella temporanea e finalizzaSpostati nella cartella di destinazione definitiva, elimina la sandbox temporanea (che ormai non serve più) e rigenera l'autoloader di Composer per registrare la posizione finale e permanente dei file:📋 Copia via SSHcd ../public_html/
rm -rf ../drupal11tmp
composer dump-autoload🔟 Installa Drupal dal browserApri il tuo browser preferito e digita l'indirizzo del tuo sito internet:🌐 Indirizzo del sitohttps://tuodominio.itSegui la normale procedura guidata di configurazione sullo schermo inserendo le credenziali del database. La tua installazione FLAT di Drupal 11 su hosting condiviso è terminata e perfettamente funzionante!Segui la normale procedura guidata di configurazione sullo schermo inserendo le credenziali del database. La tua installazione FLAT di Drupal 11 su hosting condiviso è terminata e perfettamente funzionante!
.guida-drupal .note, .guida-drupal .danger, .guida-drupal .warning {
padding: 15px !important;
border-radius: 6px !important;
margin: 20px 0 !important;
font-size: 15px !important;
line-height: 1.5 !important;
}
.guida-drupal .note {
background-color: #ecf3fe !important;
border-left: 5px solid #1a73e8 !important;
color: #1e293b !important;
}
.guida-drupal .danger {
background-color: #fde8e8 !important;
border-left: 5px solid #e02424 !important;
color: #9b1c1c !important;
}
.guida-drupal .warning {
background-color: #fef3c7 !important;
border-left: 5px solid #d97706 !important;
color: #92400e !important;
}
.guida-drupal .comparison {
display: flex !important;
gap: 20px !important;
margin: 20px 0 !important;
flex-wrap: wrap !important;
}
.guida-drupal .comparison-col {
flex: 1 !important;
min-width: 280px !important;
background-color: #f8fafc !important;
padding: 20px !important;
border-radius: 8px !important;
border: 1px solid #e2e8f0 !important;
}
.guida-drupal .comparison-col h4 {
margin-top: 0 !important;
font-size: 16px !important;
border-bottom: 2px solid #e2e8f0 !important;
padding-bottom: 8px !important;
}
.guida-drupal .comparison-col ul {
padding-left: 20px !important;
margin-bottom: 0 !important;
}
.guida-drupal .comparison-col li {
margin-bottom: 8px !important;
font-size: 14px !important;
}
⚠️ 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 incompleta.Manchino voci di menu vitali.L'interfaccia sembri "tagliata" o i fogli di stile non funzionino correttamente.Causa: Un file .htaccess generato automaticamente da Drupal all'interno di sites/default/files/ che fa uso di alcune direttive Apache (Options) non sempre permesse dagli hosting condivisi. Spesso Apache non restituisce un errore 500 esplicito, ma blocca l'accesso ad alcuni script impedendo a Drupal di caricare gli asset.✅ SoluzioneApri il file posizionato in questo percorso:📁 Percorso del filepublic_html/sites/default/files/.htaccessTrova al suo interno questa riga esatta:🔍 Riga da individuareOptions -Indexes -ExecCGI -Includes -MultiViewsCommentala inserendo il simbolo del cancelletto all'inizio del testo:📝 Modifica da salvare#Options -Indexes -ExecCGI -Includes -MultiViewsSalva il file sul server e procedi immediatamente a ricostruire la cache di Drupal lanciando questo comando da terminale:📋 Copia via SSHcd ~/domains/tuodominio.it/public_html
php core/scripts/drupal cache:rebuildAlternativa: Se riesci comunque a navigare nei menu rimasti, puoi andare su /admin/config/development/performance e cliccare sul pulsante "Svuota tutte le cache". L'interfaccia grafica tornerà immediatamente alla normalità.📌 Nota: Ricorda che alcuni aggiornamenti importanti di Drupal (eseguibili tramite composer update) potrebbero rigenerare da zero il file .htaccess nella cartella files/. Se il problema della grafica monca si ripresenta in futuro, ti basterà ripetere questa rapida modifica.🚫 Perché evitare gli installer automatici (tipo "installazione in 1 click")⚠️ ATTENZIONE: Molti hosting commerciali offrono all'interno del pannello dei pulsanti pronti del tipo "Installa Drupal in 1 click". Sebbene possa sembrare una scelta comoda ed immediata, si rivela quasi sempre una trappola strutturale. Ecco i motivi principali per cui dovresti evitarli.❌ I problemi delle installazioni automaticheNessuna gestione delle dipendenze: Il core moderno di Drupal si appoggia a decine di librerie PHP esterne di alto livello (come Symfony, Guzzle, Twig). Un installer automatico si limita a fornirti questi componenti già "impacchettati" e statici, privandoti di un vero sistema di controllo.Il file composer.lock non esiste o è incompleto: Questo è il punto più critico. Il file composer.lock ha il compito fondamentale di congelare con precisione chirurgica la versione di ogni singola libreria e modulo installato nel sistema. Senza questo file, non hai alcuna certezza su cosa sia realmente in esecuzione sul tuo spazio web.Nessuna mappatura delle versioni: Quando utilizzi Composer, ogni singolo pacchetto dichiara una versione definita (ad esempio symfony/http-foundation: v6.4.0). Con gli installer ad un click ti ritrovi una "zuppa" di file mescolati senza tracciabilità del software.Aggiornamenti disastrosi: Quando proverai ad aggiornare una versione di Drupal installata automaticamente, il sito molto probabilmente smetterà di funzionare poiché mancano i file storici che indicano a Composer quali versioni di librerie terze fossero presenti prima del processo.Impossibile aggiungere moduli moderni: La sintassi composer require drupal/nome_modulo rappresenta lo standard assoluto per espandere il CMS. Negli installer automatici questa funzione è spesso bloccata o genera conflitti distruttivi.Struttura e percorsi fragili: Questi sistemi alterano i percorsi predefiniti di Drupal creando configurazioni anomale sui server condivisi che rompono la compatibilità con i futuri moduli di terze parti.📊 Il cuore del problema: composer.lock e la mappatura delle dipendenzeQuando installi Drupal utilizzando Composer in modo nativo, il sistema si appoggia su due file di testo essenziali:📄 Ruoli dei file di configurazionecomposer.json → Specifica cosa desideri installare (es. "drupal/core": "^11")
composer.lock → Registra cosa hai installato ESATTAMENTE (es. "twig/twig": "3.8.0")Il file composer.lock funge da vera e capita "mappa catastale" del tuo intero applicativo web, catalogando ogni dipendenza e sottodipendenza insieme al rispettivo hash crittografico di integrità. Gli installer in un click rompono questo equilibrio perché:❌ Il file composer.lock è completamente assente.❌ Oppure viene inserito un file fasullo generato in modo artificiale.❌ La cartella vendor/ diventa un ammasso statico di codice non tracciabile.✅ Con Composer (questa guida)File composer.json e composer.lock reali e coerenti.Ogni pacchetto ha una versione specifica e sicura.Mappatura completa e nativa di tutte le sottodipendenze.Aggiornamenti stabili e rapidi con il comando composer update.Moduli aggiuntivi installabili in pochi secondi.Possibilità di ricostruire l'intero progetto da zero in qualsiasi momento.Piena compatibilità con le strutture degli hosting condivisi.Standard di sviluppo pulito e professionale.❌ Con installer automaticoFile composer.lock assente, incompleto o corrotto.Versioni reali delle librerie interne del tutto sconosciute.Nessuna mappatura nativa o sicura delle dipendenze PHP.Rischio altissimo di rompere il database durante gli aggiornamenti.Gestione dei moduli obsoleta via FTP come nel 2005.Impossibilità di replicare l'installazione su altri server di test.Frequenti problemi e blocchi di permessi con i server condivisi.Approccio limitato a utilizzi puramente hobbistici.🎯 Cosa fare se hai già usato un installer automatico?Se sul tuo spazio web è già attiva un'installazione di Drupal creata tramite un tool automatico ad un click, ti trovi davanti a due opzioni:Rimuovere tutto e reinstallare seguendo questa guida: È la scelta che ti consiglio caldamente. Richiede pochissimo tempo e ti garantisce fin da subito una piattaforma web professionale, sicura, robusta e aggiornabile per gli anni a venire.