2026-06-01 22:55:50 +02:00
<! DOCTYPE html >
< html lang = " it " >
< head >
< meta charset = " utf-8 " >
< title > {{ $appName ? ? 'Glastree' }} — Guida alla Configurazione </ title >
< style >
* { margin : 0 ; padding : 0 ; box - sizing : border - box ; }
body {
font - family : 'Segoe UI' , Tahoma , Geneva , Verdana , sans - serif ;
font - size : 11 pt ;
line - height : 1.6 ;
color : #333;
padding : 30 px 40 px ;
}
h1 { font - size : 22 pt ; color : #1a237e; margin-bottom: 5px; }
h2 { font - size : 16 pt ; color : #283593; margin-top: 28px; margin-bottom: 10px; border-bottom: 2px solid #e0e0e0; padding-bottom: 4px; }
h3 { font - size : 13 pt ; color : #303f9f; margin-top: 20px; margin-bottom: 8px; }
h4 { font - size : 12 pt ; color : #3949ab; margin-top: 16px; margin-bottom: 6px; }
h5 { font - size : 11 pt ; color : #5c6bc0; margin-top: 14px; margin-bottom: 5px; }
h6 { font - size : 11 pt ; color : #5c6bc0; margin-top: 12px; margin-bottom: 4px; }
p { margin - bottom : 8 px ; }
ul , ol { margin : 6 px 0 10 px 20 px ; }
li { margin - bottom : 3 px ; }
table { width : 100 % ; border - collapse : collapse ; margin : 10 px 0 ; font - size : 10 pt ; }
th , td { border : 1 px solid #ccc; padding: 6px 8px; text-align: left; }
th { background : #e8eaf6; font-weight: 600; }
code { background : #f5f5f5; padding: 1px 5px; border-radius: 3px; font-family: 'Consolas', 'Courier New', monospace; font-size: 9.5pt; color: #c62828; }
pre { background : #263238; color: #e0e0e0; padding: 12px 16px; border-radius: 5px; font-family: 'Consolas', 'Courier New', monospace; font-size: 9pt; line-height: 1.4; overflow-x: auto; margin: 8px 0 14px; white-space: pre-wrap; word-break: break-word; }
pre code { background : none ; color : inherit ; padding : 0 ; font - size : inherit ; }
. callout { border - left : 4 px solid ; padding : 10 px 14 px ; margin : 12 px 0 ; background : #f5f5f5; border-radius: 0 4px 4px 0; }
. callout - info { border - color : #2196f3; background: #e3f2fd; }
. callout - danger { border - color : #f44336; background: #ffebee; }
. callout - warning { border - color : #ff9800; background: #fff3e0; }
. callout - success { border - color : #4caf50; background: #e8f5e9; }
. badge { display : inline - block ; padding : 2 px 7 px ; font - size : 9 pt ; border - radius : 3 px ; background : #e0e0e0; }
. badge - primary { background : #1976d2; color: #fff; }
. badge - success { background : #388e3c; color: #fff; }
. badge - info { background : #0288d1; color: #fff; }
. badge - secondary { background : #757575; color: #fff; }
. subtitle { font - size : 12 pt ; color : #666; margin-bottom: 20px; }
. page - break { page - break - before : always ; }
hr { border : none ; border - top : 1 px solid #ddd; margin: 24px 0; }
. toc { margin : 20 px 0 ; padding : 16 px 20 px ; background : #f5f5f5; border-radius: 5px; }
. toc a { color : #1565c0; text-decoration: none; }
. toc li { margin - bottom : 5 px ; }
@ media print {
body { padding : 0 ; font - size : 10 pt ; }
pre { font - size : 8 pt ; padding : 8 px 12 px ; }
h2 { page - break - after : avoid ; }
h3 , h4 , h5 { page - break - after : avoid ; }
. callout , table , pre { page - break - inside : avoid ; }
}
</ style >
</ head >
< body >
< h1 > {{ $appName ? ? 'Glastree' }} </ h1 >
< p class = " subtitle " > Guida completa alla configurazione , installazione e migrazione </ p >
< div class = " toc " >
< strong > Indice </ strong >
< ol >
< li >< a href = " #webdav " > WebDAV / Nextcloud </ a ></ li >
< li >< a href = " #googledrive " > Google Drive </ a ></ li >
< li >< a href = " #tipologie " > Tipologie e Gestione Dati </ a ></ li >
< li >< a href = " #email " > Email / SMTP </ a ></ li >
< li >< a href = " #installazione " > Guida all 'Installazione</a></li>
<li><a href="#backup">Backup e Migrazione Server</a></li>
<li><a href="#docker">Docker</a></li>
</ol>
</div>
{{-- 1. WebDAV / Nextcloud --}}
<h2 id="webdav">1. WebDAV / Nextcloud</h2>
<h3>Cos' è </ h3 >
< p > WebDAV è un protocollo che permette di accedere a file su server remoti . Nextcloud lo utilizza per la sincronizzazione dei file .</ p >
< h3 > Configurazione </ h3 >
< p > Vai in < strong > Impostazioni → Repository </ strong > e crea un nuovo repository di tipo WebDAV .</ p >
< div class = " callout callout-info " >
< h4 > Campi obbligatori </ h4 >
< dl >
< dt >< strong > Nome </ strong ></ dt >
< dd > Un nome descrittivo ( es . " Nextcloud Lavoro " ) </ dd >
< dt >< strong > Base URI </ strong ></ dt >
< dd > L 'URL del tuo server WebDAV.<br>
<em>Nextcloud:</em> <code>https://tuodominio.it/remote.php/dav/files/utente/</code><br>
<em>Altri:</em> <code>https://server.webdav.it/</code></dd>
<dt><strong>Root</strong></dt>
<dd>Percorso base all' interno del server ( es . < code >/ Documenti /</ code > ) . Lascia < code >/</ code > per usare la root .</ dd >
< dt >< strong > Username </ strong ></ dt >
< dd > Il tuo nome utente </ dd >
< dt >< strong > Password </ strong ></ dt >
< dd > La password dell 'account</dd>
<dt><strong>Auth Type</strong></dt>
<dd><code>Basic</code> per la maggior parte dei server (Nextcloud, ownCloud).</dd>
</dl>
</div>
<h3>Nome utente con @ (chiocciola)</h3>
<p>Se il tuo nome utente contiene il carattere <code>@</code> (es. <code>mario.rossi@azienda.com</code>), segui queste regole:</p>
<ul>
<li><strong>Nel campo "Base URI":</strong> l' indirizzo email deve essere < strong > URL - encoded </ strong >:< br >
< code > https :// server . it / remote . php / dav / files / mario . rossi % 40 azienda . com /</ code >< br >
< small > ( il carattere < code >@</ code > diventa < code >% 40 </ code > ) </ small ></ li >
< li >< strong > Nel campo " Username " :</ strong > inserisci l 'indirizzo email <strong>normale</strong> con la <code>@</code> vera.</li>
</ul>
<p>Il sistema gestisce automaticamente la differenza tra l' URI ( che richiede < code >% 40 </ code > ) e l 'autenticazione (che usa la <code>@</code> reale).</p>
<h3>Test connessione</h3>
<p>Dopo aver salvato, usa il pulsante <strong>Test</strong> nella tabella dei repository per verificare che la connessione funzioni.</p>
<h3>Importare file</h3>
<p>Apri la sezione <strong>Documenti</strong>, clicca sul pulsante del repository nella toolbar per sfogliare i file remoti, poi clicca <strong>Salva tra i documenti</strong> su un file per importarlo come documento locale.</p>
<div class="page-break"></div>
{{-- 2. Google Drive --}}
<h2 id="googledrive">2. Google Drive</h2>
<h3>Cos' è </ h3 >
< p > Integrazione con Google Drive per sfogliare e importare file direttamente dal tuo spazio Google Drive .</ p >
< h3 > Requisiti </ h3 >
< ol >
< li > Un account Google / Google Workspace </ li >
< li > Un progetto sulla < strong > Google Cloud Console </ strong > con l 'API Google Drive abilitata</li>
<li>Credenziali OAuth 2.0 (Client ID e Client Secret)</li>
</ol>
<h3>Passo 1: Creare il progetto Google Cloud</h3>
<ol>
<li>Vai su <strong>Google Cloud Console</strong> (console.developers.google.com)</li>
<li>Crea un nuovo progetto o selezionane uno esistente</li>
<li>Vai a <strong>API e servizi → Libreria</strong></li>
<li>Cerca "<strong>Google Drive API</strong>" e <strong>abilitala</strong></li>
<li>Vai a <strong>API e servizi → Credenziali</strong></li>
<li>Clicca "<strong>Crea credenziali → ID client OAuth</strong>"</li>
<li>Tipo applicazione: "<strong>Applicazione Web</strong>"</li>
<li><strong>URI di reindirizzamento autorizzato:</strong> aggiungi <code>{{ url(' / auth / google - drive / callback ') }}</code></li>
<li>Completa la creazione e <strong>copia Client ID e Client Secret</strong></li>
</ol>
<h3>Passo 2: Configurazione nell' app </ h3 >
< ol >
< li > Vai in < strong > Impostazioni → Repository </ strong ></ li >
< li > Clicca " <strong>Nuovo Repository</strong> " e seleziona tipo < strong > Google Drive </ strong ></ li >
< li > Inserisci un nome descrittivo ( es . " Drive Lavoro " ) </ li >
< li > Incolla < strong > Client ID </ strong > e < strong > Client Secret </ strong ></ li >
< li >< strong > Folder ID ( opzionale ) :</ strong > se vuoi limitare l 'accesso a una cartella specifica, inserisci il suo ID (lo trovi nell' URL quando apri la cartella in Google Drive : < code > https :// drive . google . com / drive / folders /< strong > ID_QUI </ strong ></ code > ) </ li >
< li > Clicca " <strong>Autorizza Google Drive</strong> " — verrai reindirizzato a Google per concedere i permessi </ li >
< li > Dopo l 'autorizzazione, il refresh token verrà salvato automaticamente</li>
</ol>
<h3>Google Drive API non abilitata</h3>
<p>Se vedi l' errore < em > " Google Drive API non abilitata " </ em > nel test connessione , significa che l 'API Drive non è stata attivata nel tuo progetto Google Cloud.</p>
<div class="callout callout-danger">
<h4>Soluzione</h4>
<p>Vai su <code>https://console.developers.google.com/apis/api/drive.googleapis.com/overview</code></p>
<p>Seleziona il progetto corretto dall' header in alto , clicca < strong > " Enable " </ strong > e attendi qualche minuto prima di riprovare .</ p >
</ div >
< h3 > Importare file </ h3 >
< p > Stessa procedura di WebDAV : apri < strong > Documenti </ strong > , clicca sul repository Drive , sfoglia i file e usa < strong > Salva tra i documenti </ strong >.</ p >
< h3 > File Google ( Documenti , Fogli , Presentazioni ) </ h3 >
< p > I file creati con Google Workspace ( Documenti Google , Fogli Google , Presentazioni Google , Disegni Google ) non possono essere scaricati direttamente perché non hanno un formato binario nativo .</ p >
< p > Il sistema li converte automaticamente in formato Office Open XML durante l 'import:</p>
<table>
<thead><tr><th>File Google</th><th>Formato convertito</th></tr></thead>
<tbody>
<tr><td>Documento Google</td><td><code>.docx</code> (Word)</td></tr>
<tr><td>Foglio Google</td><td><code>.xlsx</code> (Excel)</td></tr>
<tr><td>Presentazione Google</td><td><code>.pptx</code> (PowerPoint)</td></tr>
<tr><td>Disegno Google</td><td><code>.png</code> (Immagine)</td></tr>
<tr><td>Altri (Moduli, Script)</td><td><code>.pdf</code> (PDF)</td></tr>
</tbody>
</table>
<p>Il nome del file viene automaticamente esteso con l' estensione corretta ( es . " Relazione " → " Relazione.docx " ) .</ p >
< div class = " page-break " ></ div >
{{ -- 3. Tipologie e Dati -- }}
< h2 id = " tipologie " > 3. Tipologie e Gestione Dati </ h2 >
< h3 > Tipologie Documenti </ h3 >
< p > Le tipologie classificano i documenti ( avatar , galleria , documento , statuto , altro ) .</ p >
< p > Si gestiscono in < strong > Impostazioni → Tipologie Documenti </ strong >. Puoi aggiungere , rinominare , riordinare ed eliminare tipologie ( tranne quelle con documenti associati ) .</ p >
< h3 > Tipologie Individui </ h3 >
< p > Classificano gli individui ( es . socio , volontario , dipendente ) . Si gestiscono in < strong > Impostazioni → Tipologie </ strong >.</ p >
< h3 > Tipologie Eventi </ h3 >
< p > Classificano gli eventi ( es . riunione , assemblea , formazione ) . Si gestiscono in < strong > Impostazioni → Tipologie Eventi </ strong >.</ p >
< h3 > Ruoli Individui </ h3 >
< p > Definiscono il ruolo o la carica di un individuo ( es . presidente , segretario , tesoriere ) . Si gestiscono in < strong > Impostazioni → Ruoli </ strong >.</ p >
< h3 > Visibilità Documenti </ h3 >
< p > Ogni documento può avere diversi livelli di visibilità :</ p >
< ul >
< li >< strong > Pubblico </ strong > — visibile a tutti gli utenti </ li >
< li >< strong > Individuo </ strong > — visibile solo a uno specifico individuo </ li >
< li >< strong > Gruppo </ strong > — visibile solo ai membri di un gruppo </ li >
< li >< strong > Evento </ strong > — visibile solo ai partecipanti di un evento </ li >
< li >< strong > Mailing </ strong > — visibile solo ai membri di una mailing list </ li >
</ ul >
< div class = " page-break " ></ div >
{{ -- 4. Email / SMTP -- }}
< h2 id = " email " > 4. Email / SMTP </ h2 >
< h3 > Configurazione Email </ h3 >
< p > Vai in < strong > Impostazioni → Email </ strong > per configurare la posta elettronica .</ p >
< h3 > Server IMAP ( Ricezione ) </ h3 >
< p > Usato per ricevere e leggere le email direttamente nell 'app.</p>
<div class="callout callout-info">
<h4>Campi consigliati per provider comuni</h4>
<table>
<thead><tr><th>Provider</th><th>Host</th><th>Porta</th><th>Crittografia</th></tr></thead>
<tbody>
<tr><td>Gmail</td><td><code>imap.gmail.com</code></td><td><code>993</code></td><td>SSL</td></tr>
<tr><td>Outlook/Office 365</td><td><code>outlook.office365.com</code></td><td><code>993</code></td><td>SSL</td></tr>
<tr><td>Libero</td><td><code>imapmail.libero.it</code></td><td><code>993</code></td><td>SSL</td></tr>
<tr><td>Aruba</td><td><code>imap.aruba.it</code></td><td><code>993</code></td><td>SSL</td></tr>
</tbody>
</table>
</div>
<h3>Server SMTP (Invio)</h3>
<p>Usato per inviare email dall' app . Supporta account multipli ( mittenti ) .</ p >
< div class = " callout callout-info " >
< h4 > Campi consigliati per provider comuni </ h4 >
< table >
< thead >< tr >< th > Provider </ th >< th > Host </ th >< th > Porta </ th >< th > Crittografia </ th ></ tr ></ thead >
< tbody >
< tr >< td > Gmail </ td >< td >< code > smtp . gmail . com </ code ></ td >< td >< code > 587 </ code ></ td >< td > TLS </ td ></ tr >
< tr >< td > Outlook / Office 365 </ td >< td >< code > smtp . office365 . com </ code ></ td >< td >< code > 587 </ code ></ td >< td > TLS </ td ></ tr >
< tr >< td > Libero </ td >< td >< code > smtp . libero . it </ code ></ td >< td >< code > 465 </ code ></ td >< td > SSL </ td ></ tr >
< tr >< td > Aruba </ td >< td >< code > smtp . aruba . it </ code ></ td >< td >< code > 465 </ code ></ td >< td > SSL </ td ></ tr >
</ tbody >
</ table >
</ div >
< h3 > Gmail / Google Workspace </ h3 >
< div class = " callout callout-warning " >
Gmail richiede una < strong > Password per l 'app</strong> (non la password normale) se usi la verifica in due passaggi. Puoi generarla su <code>https://myaccount.google.com/apppasswords</code>.
</div>
<h3>Mailing</h3>
<p>Le <strong>Mailing List</strong> permettono di inviare email a gruppi predefiniti di destinatari.</p>
<ul>
<li>Crea una mailing list in <strong>Mailing List → Nuova</strong></li>
<li>Puoi popolare la lista da individui, gruppi o manualmente</li>
<li>Invia email alla lista da <strong>Email → Nuova Email</strong>, selezionando la mailing list come destinatario</li>
</ul>
<h3>Test connessione</h3>
<p>Dopo aver configurato i server, usa il pulsante <strong>Test Connessione</strong> per verificare che IMAP e SMTP funzionino correttamente.</p>
<div class="page-break"></div>
{{-- 5. Installazione --}}
<h2 id="installazione">5. Guida all' Installazione </ h2 >
< h3 > Panoramica </ h3 >
2026-06-03 09:09:46 +02:00
< p > L 'installazione avviene tramite comandi <strong>Artisan</strong> da terminale. Non esiste un wizard web interattivo. Supporta due modalità:</p>
2026-06-01 22:55:50 +02:00
<table>
<thead><tr><th>Modalità</th><th>Descrizione</th></tr></thead>
<tbody>
<tr><td><strong>Fresh Install</strong></td><td>Installa l' applicazione da zero su un nuovo server : crea il database , esegue le migration , popola i dati di base e crea l 'amministratore.</td></tr>
<tr><td><strong>Restore da Backup</strong></td><td>Ripristina un' installazione esistente da un file ZIP di backup : importa il database , ripristina i documenti e la configurazione .</ td ></ tr >
</ tbody >
</ table >
< h3 > Requisiti del Server </ h3 >
< table >
< thead >< tr >< th > Componente </ th >< th > Versione Minima </ th >< th > Note </ th ></ tr ></ thead >
< tbody >
< tr >< td > Web Server </ td >< td > Apache 2.4 +</ td >< td > Con mod_rewrite abilitato </ td ></ tr >
< tr >< td > PHP </ td >< td > 8.2 + ( consigliato 8.4 ) </ td >< td > Estensioni : pdo_mysql , mbstring , xml , curl , zip , gd , fileinfo </ td ></ tr >
< tr >< td > MySQL / MariaDB </ td >< td > MySQL 8.0 + / MariaDB 10.5 +</ td >< td > Supporto utf8mb4 </ td ></ tr >
< tr >< td > Composer </ td >< td > 2. x </ td >< td > Per gestione dipendenze PHP </ td ></ tr >
< tr >< td > Node . js / npm </ td >< td > Node 20 + / npm 10 +</ td >< td > Per compilazione asset frontend ( opzionale se precompilati ) </ td ></ tr >
</ tbody >
</ table >
< h3 > Installazione Passo - Passo </ h3 >
< h4 > Passo 1 : Preparare il server LAMP </ h4 >
< pre > sudo apt update && sudo apt upgrade - y
sudo apt install - y apache2 mariadb - server php8 . 4 php8 . 4 - cli \
php8 . 4 - mysql php8 . 4 - xml php8 . 4 - mbstring php8 . 4 - curl \
php8 . 4 - zip php8 . 4 - bcmath php8 . 4 - gd php8 . 4 - intl \
composer git unzip
sudo a2enmod rewrite
sudo systemctl restart apache2 </ pre >
< h4 > Passo 2 : Ottenere l 'applicazione</h4>
<p>Puoi clonare il repository con git oppure estrarre il file ZIP ricevuto nella cartella <code>/var/www/glastree</code>.</p>
<pre>cd /var/www
# Opzione A — Git clone
git clone <URL_REPOSITORY> glastree
# Opzione B — ZIP (se non hai git)
# unzip /percorso/del/glastree.zip -d glastree
cd glastree
composer install --no-dev --optimize-autoloader
npm ci && npm run build</pre>
<p>Se non hai accesso a npm, puoi saltare il build. L' interfaccia userà comunque AdminLTE via CDN .</ p >
< h4 > Passo 3 : Permessi cartelle </ h4 >
< pre > sudo chown - R www - data : www - data storage bootstrap / cache
sudo chmod - R 775 storage bootstrap / cache </ pre >
< h4 > Passo 4 : Configurare Apache </ h4 >
< pre > sudo tee / etc / apache2 / sites - available / glastree . conf & lt ; & lt ; APACHE
& lt ; VirtualHost *: 80 & gt ;
ServerName glastree . esempio . it
DocumentRoot / var / www / glastree / public
& lt ; Directory / var / www / glastree / public & gt ;
Options - Indexes + FollowSymLinks
AllowOverride All
Require all granted
& lt ; / Directory & gt ;
ErrorLog \ $ { APACHE_LOG_DIR } / glastree_error . log
CustomLog \ $ { APACHE_LOG_DIR } / glastree_access . log combined
& lt ; / VirtualHost & gt ;
APACHE
sudo a2dissite 000 - default . conf
sudo a2ensite glastree . conf
sudo systemctl reload apache2 </ pre >
2026-06-03 09:09:46 +02:00
< h4 > Passo 5 : Configurare l 'ambiente</h4>
<pre># Copia il file di configurazione di esempio
cp .env.example .env
2026-06-01 22:55:50 +02:00
2026-06-03 09:09:46 +02:00
# Genera la chiave di crittografia (obbligatorio)
php artisan key:generate
2026-06-01 22:55:50 +02:00
2026-06-03 09:09:46 +02:00
# Modifica .env con i parametri del tuo database:
# nano .env
# DB_DATABASE=glastree
# DB_USERNAME=glastree
# DB_PASSWORD=la_tua_password</pre>
<h4>Passo 6: Eseguire l' installazione </ h4 >
< p >< strong > Fresh Install :</ strong ></ p >
< pre > # Esegui migration e seed dei dati di base
php artisan migrate -- seed
# Crea il collegamento storage
php artisan storage : link
# Crea l'utente amministratore
php artisan tinker -- execute = "
\$ u = new \ App \ Models \ User;
\$ u->name = 'Admin';
\$ u->email = 'admin@esempio.it';
\$ u->password = bcrypt('password_sicura');
\$ u->save();
" </ pre >
< p >< strong > Restore da Backup :</ strong ></ p >
< pre > # Importa il database
# mysql -u root -p glastree < database.sql
# Ripristina i file dei documenti
# tar -xzf storage.tar.gz -C storage/
# Rigenera APP_KEY
php artisan key : generate
# Crea il collegamento storage
php artisan storage : link </ pre >
2026-06-01 22:55:50 +02:00
< h3 > Modalità Fresh Install </ h3 >
< p > Seleziona questa modalità quando installi l 'applicazione per la prima volta su un server.</p>
<p>Cosa succede durante l' installazione :</ p >
< ol >
< li > Genera < code > APP_KEY </ code > per la crittografia </ li >
< li > Esegue tutte le migration per creare le tabelle del database </ li >
< li > Popola i dati di base ( diocesi , comuni , ruoli , preset ) </ li >
< li > Crea il collegamento < code > storage → public / storage </ code ></ li >
< li > Crea l 'utente amministratore con i permessi completi</li>
</ol>
<h3>Modalità Restore da Backup</h3>
<p>Seleziona questa modalità quando vuoi migrare un' installazione esistente su un nuovo server .</ p >
< p > Cosa serve :</ p >
< ul >
< li > Un file ZIP generato dalla pagina < strong > Admin → Backup </ strong > del server originale </ li >
< li > Il wizard accetta upload diretto del file o un percorso sul server </ li >
</ ul >
< p > Cosa succede durante il restore :</ p >
< ol >
< li > Estrae il file ZIP in una cartella temporanea </ li >
< li > Importa < code > database . sql </ code > nel database MySQL configurato </ li >
< li > Copia i file documenti in < code > storage / app / documenti /</ code ></ li >
< li > Ripristina il file < code >. env </ code > dal backup ( preservando le credenziali DB del nuovo server ) </ li >
</ ol >
< h3 > Dopo l 'Installazione</h3>
<ol>
<li><strong>Configura SSL</strong> con Let' s Encrypt :
< pre > sudo apt install - y certbot python3 - certbot - apache
sudo certbot -- apache - d glastree . esempio . it </ pre >
</ li >
< li >< strong > Accedi </ strong > con le credenziali amministratore create durante l 'installazione</li>
<li><strong>Configura l' applicazione </ strong > in Impostazioni :
< ul >
< li > Nome applicazione e logo </ li >
< li > Email ( SMTP per invio , IMAP per ricezione ) </ li >
< li > Repository remoti ( Google Drive , Nextcloud ) </ li >
</ ul >
</ li >
< li >< strong > Crea utenti </ strong > dal pannello Admin → Utenti </ li >
< li >< strong > Configura il cron </ strong > per backup automatico e sync email :
< pre > sudo crontab - u www - data - e
# Inserisci:
* * * * * cd / var / www / glastree && php artisan schedule : run >> / dev / null 2 >& 1 </ pre >
</ li >
</ ol >
< h3 > Risoluzione Problemi </ h3 >
< div class = " callout callout-danger " >
< h4 > Errore " 500 | Server Error " dopo l 'installazione</h4>
<p>Probabilmente mancano permessi sulle cartelle <code>storage</code> o <code>bootstrap/cache</code>:</p>
<pre>sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache</pre>
</div>
<div class="callout callout-danger">
<h4>Errore "No application encryption key"</h4>
<p>APP_KEY non generata. Nella cartella dell' app :</ p >
< pre > php artisan key : generate </ pre >
</ div >
< div class = " callout callout-warning " >
< h4 > mod_rewrite non funziona </ h4 >
< p > Se le rotte restituiscono 404 , verifica che Apache abbia AllowOverride :</ p >
< pre > sudo a2enmod rewrite
# Nel VirtualHost: AllowOverride All
sudo systemctl reload apache2 </ pre >
</ div >
< div class = " page-break " ></ div >
{{ -- 6. Backup e Migrazione -- }}
< h2 id = " backup " > 6. Backup e Migrazione Server </ h2 >
< h3 > Cos 'è</h3>
<p>Il sistema di backup crea un archivio ZIP contenente tutto il necessario per ripristinare l' applicazione su un nuovo server . Include database , file caricati e configurazione .</ p >
< h3 > Cosa include il backup </ h3 >
< table >
< thead >< tr >< th > Componente </ th >< th > Incluso </ th >< th > Dettagli </ th ></ tr ></ thead >
< tbody >
< tr >< td > Database ( MySQL ) </ td >< td > Sempre </ td >< td > Struttura , dati , stored procedure , eventi , trigger </ td ></ tr >
< tr >< td > File caricati </ td >< td > Opzionale </ td >< td > Documenti , avatar , gallerie </ td ></ tr >
< tr >< td > Configurazione . env </ td >< td > Opzionale </ td >< td > APP_KEY , credenziali DB , SMTP , token OAuth </ td ></ tr >
< tr >< td > Metadati </ td >< td > Sempre </ td >< td > Versione app , PHP , Laravel </ td ></ tr >
</ tbody >
</ table >
< h3 > Come eseguire un backup </ h3 >
< table >
< thead >< tr >< th > Via Interfaccia Web </ th >< th > Via Comando </ th ></ tr ></ thead >
< tbody >
< tr >
< td >
< ol >
< li > Vai su < strong > Admin → Backup </ strong ></ li >
< li > Verifica le impostazioni ( includi files /. env ) </ li >
< li > Clicca < strong > Esegui Backup Ora </ strong ></ li >
< li > Scarica il file ZIP generato </ li >
</ ol >
</ td >
< td >
< pre > php artisan backup : run </ pre >
< p > Il file viene creato in < code > storage / app / backups /</ code ></ p >
</ td >
</ tr >
</ tbody >
</ table >
< h3 > Backup automatico </ h3 >
< p > Puoi abilitare il backup automatico dalla pagina < strong > Admin → Backup </ strong >:</ p >
< ul >
< li >< strong > Frequenza :</ strong > giornaliero , settimanale o mensile </ li >
< li >< strong > Ora :</ strong > consigliata 03 : 00 ( notte ) </ li >
< li >< strong > Requisito :</ strong > il cron di Laravel deve essere configurato sul server </ li >
</ ul >
< div class = " callout callout-warning " >
< i class = " fas fa-clock mr-2 " ></ i >
Per il backup automatico , aggiungi questo cron :
< pre >* * * * * cd {{ base_path () }} && php artisan schedule : run >> / dev / null 2 >& 1 </ pre >
</ div >
< hr >
< h3 > Procedura di Migrazione Completa </ h3 >
< p > Segui questa procedura per migrare l 'applicazione su un nuovo server LAMP (Linux, Apache, MySQL, PHP).</p>
<div class="callout callout-danger">
<strong>ATTENZIONE: APP_KEY</strong>
<p>L' APP_KEY cripta i dati sensibili ( password email SMTP , token OAuth Google Drive , ecc . ) .</ p >
< ul >
< li >< strong > Se hai il . env originale dal backup :</ strong > NON rigenerare APP_KEY — mantieni i dati criptati accessibili .</ li >
< li >< strong > Se hai perso il . env :</ strong > DEVI rigenerare APP_KEY , ma perderai l 'accesso ai dati criptati esistenti. Dovrai riconfigurare SMTP e OAuth.</li>
</ul>
</div>
<h4>Passo 1: Preparazione del server</h4>
<pre>sudo apt update && sudo apt upgrade -y</pre>
<h4>Passo 2: Installa LAMP + PHP 8.4</h4>
<pre>sudo apt install -y apache2 mariadb-server php8.4 php8.4-cli \
php8.4-mysql php8.4-xml php8.4-mbstring php8.4-curl \
php8.4-zip php8.4-bcmath php8.4-gd php8.4-intl \
composer git unzip
sudo a2enmod rewrite</pre>
<h4>Passo 3: Ottieni l' applicazione </ h4 >
< p > Puoi clonare il repository con git oppure estrarre il file ZIP ricevuto nella cartella < code >/ var / www / glastree </ code >.</ p >
< pre > cd / var / www
# Opzione A — Git clone
git clone & lt ; URL_REPOSITORY & gt ; glastree
# Opzione B — ZIP (se non hai git)
# unzip /percorso/del/glastree.zip -d glastree
cd glastree
composer install -- no - dev -- optimize - autoloader
npm ci && npm run build </ pre >
< h4 > Passo 4 : Carica il backup </ h4 >
< p > Copia il file < code > backup . zip </ code > sul nuovo server e estrailo :</ p >
< pre > mkdir - p / tmp / restore
unzip backup . zip - d / tmp / restore /
ls - la / tmp / restore /
# Dovresti vedere: database.sql .env files/ manifest.json</pre>
< h4 > Passo 5 : Crea database e importa </ h4 >
< pre > sudo mysql - u root & lt ; & lt ; EOF
CREATE DATABASE glastree CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ;
CREATE USER 'glastree' @ 'localhost' IDENTIFIED BY 'ScegliPasswordFortep4ss!' ;
GRANT ALL ON glastree .* TO 'glastree' @ 'localhost' ;
FLUSH PRIVILEGES ;
EOF
mysql - u glastree - p glastree & lt ; / tmp / restore / database . sql </ pre >
< h4 > Passo 6 : Configura . env </ h4 >
< pre > cp / tmp / restore /. env . env
# Modifica se necessario:
# APP_URL=https://nuovo-dominio.it
# DB_HOST=localhost
# DB_DATABASE=glastree
# DB_USERNAME=glastree
# DB_PASSWORD=ScegliPasswordFortep4ss!
# DECIDI SULL'APP_KEY (leggi avviso sopra!)
# php artisan key:generate ← SOLO se non hai il .env originale</pre>
< h4 > Passo 7 : Ripristina file e permessi </ h4 >
< pre > cp - r / tmp / restore / files /* storage/app/documenti/
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 755 storage bootstrap/cache
php artisan storage:link</pre>
<h4>Passo 8: Cache</h4>
<pre>php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache</pre>
<h4>Passo 9: Configura Apache</h4>
<pre>sudo tee /etc/apache2/sites-available/glastree.conf <<APACHE
<VirtualHost *:80>
ServerName glastree.esempio.it
DocumentRoot /var/www/glastree/public
<Directory /var/www/glastree/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/glastree_error.log
CustomLog \${APACHE_LOG_DIR}/glastree_access.log combined
</VirtualHost>
APACHE
sudo a2dissite 000-default.conf
sudo a2ensite glastree.conf
sudo systemctl reload apache2</pre>
<h4>Passo 10: SSL Let's Encrypt</h4>
<pre>sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d glastree.esempio.it</pre>
<h4>Passo 11: Cron per backup automatico</h4>
<pre>sudo crontab -u www-data -e
# Inserisci:
* * * * * cd /var/www/glastree && php artisan schedule:run >> /dev/null 2>&1</pre>
<h4>Passo 12: Verifica finale</h4>
<ol>
<li>Apri https://glastree.esempio.it nel browser</li>
<li>Fai login con le credenziali esistenti</li>
<li>Verifica: Dashboard, Documenti, Impostazioni, Email</li>
<li>Se hai rigenerato APP_KEY: riconfigura SMTP e OAuth Google Drive</li>
</ol>
<hr>
2026-06-03 09:09:46 +02:00
<h3>Comandi Artisan</h3>
<p>Per installazione e ripristino usa i comandi Artisan da terminale. Vedi la sezione <strong>Installazione</strong> per la guida completa.</p>
2026-06-01 22:55:50 +02:00
<div class="page-break"></div>
{{-- 7. Docker --}}
<h2 id="docker">7. Docker</h2>
<h3>Creare un'immagine Docker con dati di base</h3>
<p>Puoi creare un'immagine Docker pronta all'uso che include l'applicazione e i dati di base (tipologie documenti, tipologie eventi, ruoli). Scegli la configurazione in base alle tue esigenze:</p>
<table>
<thead><tr><th>Configurazione</th><th>Descrizione</th></tr></thead>
<tbody>
<tr><td><strong>SQLite (Leggero)</strong></td><td>Database embedded, nessun servizio aggiuntivo. Ideale per demo, test, sviluppo locale o ambienti con poca concorrenza.</td></tr>
<tr><td><strong>MySQL (Standard)</strong></td><td>Database separato in un container MySQL. Configurazione standard, ideale per produzione, staging e ambienti con più utenti.</td></tr>
</tbody>
</table>
<h3>1. Dockerfile (comune a entrambe le modalità)</h3>
<pre>FROM php:8.4-apache
# Abilita mod_rewrite
RUN docker-php-ext-enable opcache \
&& a2enmod rewrite
# Installa estensioni PHP (sia SQLite che MySQL)
RUN docker-php-ext-install pdo_mysql pdo_sqlite bcmath gd zip
# Installa Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Configura DocumentRoot per Laravel
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# Copia l'applicazione
COPY . /var/www/html/
# Installa dipendenze e compila asset
RUN composer install --no-dev --optimize-autoloader \
&& mkdir -p storage/app/public \
&& mkdir -p storage/framework/cache/data \
&& mkdir -p storage/framework/sessions \
&& mkdir -p storage/framework/views \
&& mkdir -p storage/logs \
&& mkdir -p bootstrap/cache \
&& chown -R www-data:www-data storage bootstrap/cache
# Entrypoint per inizializzazione
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["apache2-foreground"]</pre>
<h3>2. Entrypoint Script (comune)</h3>
<p>Crea <code>docker-entrypoint.sh</code>. Lo script rileva automaticamente la configurazione in base alle variabili d'ambiente:</p>
<pre>#!/bin/bash
set -e
# Se .env non esiste, lo genera dalle variabili d'ambiente
if [ ! -f .env ]; then
cp .env.example .env
if [ "$DB_CONNECTION" = "mysql" ]; then
# Configura MySQL
sed -i "s/DB_CONNECTION=mysql/DB_CONNECTION=mysql/" .env
sed -i "s/DB_HOST=.*/ DB_HOST = $ { DB_HOST :- mysql } / " .env
sed -i " s / DB_PORT =.*/ DB_PORT = $ { DB_PORT :- 3306 } / " .env
sed -i " s / DB_DATABASE =.*/ DB_DATABASE = $ { DB_DATABASE :- glastree } / " .env
sed -i " s / DB_USERNAME =.*/ DB_USERNAME = $ { DB_USERNAME :- glastree } / " .env
sed -i " s / DB_PASSWORD =.*/ DB_PASSWORD = $ { DB_PASSWORD :- secret } / " .env
# Attende che MySQL sia pronto
echo " Attendo MySQL ... "
until php -r " new PDO ( 'mysql:host=${DB_HOST:-mysql};dbname=${DB_DATABASE:-glastree}' , '${DB_USERNAME:-glastree}' , '${DB_PASSWORD:-secret}' ); " 2>/dev/null; do
sleep 2
done
echo " MySQL pronto . "
else
# Configura SQLite
sed -i 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite/' .env
sed -i 's/DB_HOST=.*//' .env
sed -i 's/DB_PORT=.*//' .env
sed -i 's/DB_DATABASE=.*/DB_DATABASE= \ /var \ /www \ /html \ /database \ /database.sqlite/' .env
sed -i 's/DB_USERNAME=.*//' .env
sed -i 's/DB_PASSWORD=.*//' .env
touch database/database.sqlite
chmod 664 database/database.sqlite
fi
# Genera APP_KEY
php artisan key:generate --force
fi
# Esegui migration e seed se il database è vuoto
if [ ! -f .db_initialized ]; then
php artisan migrate --force
php artisan db:seed --force
touch .db_initialized
fi
# Configura storage link
php artisan storage:link --force 2>/dev/null || true
exec " $ @ " </pre>
<pre>chmod +x docker-entrypoint.sh</pre>
<h3>3. Seed Base Dati (comune)</h3>
<p>Per includere tipologie documenti, tipologie eventi e ruoli, crea un seeder dedicato:</p>
<pre>php artisan make:seeder DockerBaseDataSeeder</pre>
<p>Contenuto di <code>database/seeders/DockerBaseDataSeeder.php</code>:</p>
<pre><?php
declare(strict_types=1);
namespace Database \ Seeders;
use Illuminate \ Database \ Seeder;
use Illuminate \ Support \ Facades \ DB;
class DockerBaseDataSeeder extends Seeder
{
public function run(): void
{
// Tipologie Documenti
$tipologieDoc = ['documento', 'avatar', 'galleria', 'statuto', 'programma', 'locandina', 'altro'];
foreach ( $tipologieDoc as $ord => $nome ) {
DB::table('tipologie_documenti')->updateOrInsert(
['nome' => $nome ],
['descrizione' => ucfirst( $nome ), 'ordine' => $ord + 1, 'attiva' => true]
);
}
// Tipologie Eventi
$tipologieEventi = [
['nome' => 'catechesi', 'descrizione' => 'Catechesi'],
['nome' => 'liturgia', 'descrizione' => 'Liturgia'],
['nome' => 'animazione', 'descrizione' => 'Animazione'],
['nome' => 'formazione', 'descrizione' => 'Formazione'],
['nome' => 'incontro', 'descrizione' => 'Incontro'],
['nome' => 'riunione', 'descrizione' => 'Riunione'],
['nome' => 'festa', 'descrizione' => 'Festa'],
['nome' => 'altro', 'descrizione' => 'Altro'],
];
foreach ( $tipologieEventi as $ord => $t ) {
DB::table('tipologie_eventi')->updateOrInsert(
['nome' => $t['nome'] ],
['descrizione' => $t['descrizione'] , 'ordine' => $ord + 1, 'attiva' => true]
);
}
// Ruoli
$ruoli = ['presidente', 'vicepresidente', 'segretario', 'tesoriere', 'consigliere', 'volontario', 'socio', 'altro'];
foreach ( $ruoli as $ord => $nome ) {
DB::table('ruoli')->updateOrInsert(
['nome' => $nome ],
['descrizione' => ucfirst( $nome ), 'ordine' => $ord + 1, 'attiva' => true]
);
}
}
}</pre>
<p>Registralo in <code>database/seeders/DatabaseSeeder.php</code>:</p>
<pre> $this ->call([
// ... altri seeder ...
DockerBaseDataSeeder::class,
]);</pre>
<h3>4. Docker Compose</h3>
<h4>Opzione A — SQLite (leggero)</h4>
<pre>services:
glastree:
build: .
ports:
- " 8080 : 80 "
volumes:
- glastree_storage:/var/www/html/storage
- glastree_db:/var/www/html/database
environment:
- APP_ENV=production
- APP_DEBUG=false
- APP_URL=http://localhost:8080
- DB_CONNECTION=sqlite
volumes:
glastree_storage:
glastree_db:</pre>
<h4>Opzione B — MySQL (standard)</h4>
<pre>services:
glastree:
build: .
ports:
- " 8080 : 80 "
volumes:
- glastree_storage:/var/www/html/storage
depends_on:
mysql:
condition: service_healthy
environment:
- APP_ENV=production
- APP_DEBUG=false
- APP_URL=http://localhost:8080
- DB_CONNECTION=mysql
- DB_HOST=mysql
- DB_PORT=3306
- DB_DATABASE=glastree
- DB_USERNAME=glastree
- DB_PASSWORD=secret
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
environment:
- MYSQL_DATABASE=glastree
- MYSQL_USER=glastree
- MYSQL_PASSWORD=secret
- MYSQL_ROOT_PASSWORD=root_secret
healthcheck:
test: [ " CMD " , " mysqladmin " , " ping " , " - h " , " localhost " ]
interval: 5s
timeout: 3s
retries: 10
volumes:
glastree_storage:
mysql_data:</pre>
<h3>5. Build e avvio</h3>
<p>Assicurati di essere nella cartella del progetto (ottenuta via <code>git clone</code> o estraendo il ZIP), poi:</p>
<pre># Costruisci l'immagine (comune)
docker build -t glastree:latest .
# Avvia con SQLite
docker compose -f docker-compose.yml up -d
# Oppure avvia con MySQL
# docker compose -f docker-compose.mysql.yml up -d
# Apri nel browser
open http://localhost:8080</pre>
<h3>6. Primo accesso</h3>
<p>Al primo avvio, l'entrypoint esegue automaticamente migration e seed. Troverai già popolati:</p>
<ul>
<li><strong>Tipologie Documenti:</strong> documento, avatar, galleria, statuto, programma, locandina, altro</li>
<li><strong>Tipologie Eventi:</strong> catechesi, liturgia, animazione, formazione, incontro, riunione, festa, altro</li>
<li><strong>Ruoli:</strong> presidente, vicepresidente, segretario, tesoriere, consigliere, volontario, socio, altro</li>
</ul>
<p>Dovrai creare il primo utente amministratore via CLI:</p>
<pre>docker exec -it glastree php artisan tinker --execute= "
\ $u = new \App\Models\User ;
\ $u -> name = 'Amministratore' ;
\ $u -> email = 'admin@esempio.it' ;
\ $u -> password = bcrypt ( 'password-forte' );
\ $u -> is_admin = true ;
\ $u -> permissions = [ 'individui' => 2 , 'gruppi' => 2 , 'eventi' => 2 , 'documenti' => 2 , 'mailing' => 2 , 'viste' => 2 , 'report' => 2 , 'settings' => 2 ];
\ $u -> save ();
echo 'Utente creato con successo!' ;
" </pre>
<div class= " callout callout - warning " >
<h4>Note importanti</h4>
<ul>
<li><strong>Persistenza:</strong> i volumi Docker preservano storage e database tra i riavvii</li>
<li><strong>APP_KEY:</strong> viene generata al primo avvio — se elimini i volumi, la perdi e i dati criptati diventano inaccessibili</li>
<li><strong>MySQL in produzione:</strong> imposta password sicure per <code>MYSQL_PASSWORD</code> e <code>MYSQL_ROOT_PASSWORD</code></li>
<li><strong>File compose separati:</strong> puoi mantenere entrambi i file (<code>docker-compose.yml</code> per SQLite, <code>docker-compose.mysql.yml</code> per MySQL) e scegliere con <code>-f</code></li>
</ul>
</div>
</body>
</html>