# Deployment Apache

## 1. Preparazione release

Su una macchina con PHP, Composer e Node compatibili:

```bash
composer install --no-dev --prefer-dist --optimize-autoloader
npm ci
npm run build
php artisan test
composer audit --locked
npm audit
```

Creare l’archivio escludendo `.env`, `.git`, `node_modules`, test locali, log, cache e backup. Includere `vendor/` e `public/build/` se l’hosting non dispone di SSH.

## 2. Upload e document root

Struttura raccomandata:

```text
/home/account/francoach/          applicazione completa
/home/account/francoach/public/   unica document root Apache
```

Impostare la document root del dominio su `/home/account/francoach/public`. Non esporre `.env`, `vendor`, `storage`, `database`, backup o sorgenti.

Se il provider obbliga a usare `public_html`, caricare l’app in `/home/account/francoach`, copiare solo il contenuto di `public/` in `/home/account/public_html` e aggiornare in `public_html/index.php` i due percorsi:

```php
require __DIR__.'/../francoach/vendor/autoload.php';
$app = require_once __DIR__.'/../francoach/bootstrap/app.php';
```

Copiare anche `public/.htaccess` e `public/build`. Verificare che richieste a `/.env`, `/vendor/` e `/storage/logs/` restituiscano 403 o 404.

## 3. Configurazione `.env`

Creare `.env` dal modello e valorizzare almeno:

```dotenv
APP_ENV=production
APP_DEBUG=false
APP_URL=https://app.example.it
APP_TIMEZONE=Europe/Rome
APP_KEY=base64:...
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=...
DB_USERNAME=...
DB_PASSWORD=...
SESSION_SECURE_COOKIE=true
TRUSTED_PROXIES=127.0.0.1,::1
MAIL_MAILER=smtp
MAIL_HOST=...
MAIL_PORT=587
MAIL_USERNAME=...
MAIL_PASSWORD=...
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=...
BACKUP_PATH=/home/account/backups/francoach
BACKUP_ENCRYPTION_PASSPHRASE=...
MYSQLDUMP_BINARY=/usr/bin/mysqldump
```

Generare `APP_KEY` una sola volta con `php artisan key:generate`. La modifica successiva invalida sessioni e dati cifrati. Usare una passphrase backup conservata separatamente dal server.

## 4. Database, migration e seed

Creare database e utente dedicato con privilegi limitati al database FranCoach.

```bash
php artisan migrate --force
php artisan db:seed --force
```

Prima del seed configurare una password robusta in `SEED_COACH_PASSWORD`. Gli atleti vengono creati dal pannello coach tramite invito. Rimuovere la variabile seed dall’ambiente dopo l’uso oppure sostituirla con un segreto non riutilizzato.

Alternativa senza CLI: importare `database/schema/mysql-schema.sql`, quindi eseguire il seed con la procedura temporanea protetta descritta sotto. Lo SQL contiene struttura e registro migration, non utenti demo.

## 5. Storage e permessi

Con symlink disponibile:

```bash
php artisan storage:link
```

Senza symlink, creare una directory non eseguibile `/home/account/public_html/storage`, impostare:

```dotenv
PUBLIC_STORAGE_PATH=/home/account/public_html/storage
PUBLIC_STORAGE_URL=https://app.example.it/storage
```

Copiare `storage/app/public/.htaccess` nella directory e verificare che un file `.php` non sia eseguibile. Questa configurazione scrive direttamente nello storage pubblico controllato e non richiede sincronizzazioni.

Permessi consigliati:

```text
directory applicazione: 0755
file applicazione:       0644
storage/:                0750 o 0770 secondo utente Apache
bootstrap/cache/:        0750 o 0770
.env:                    0600 o 0640
backup:                  0700
```

Non usare `0777`.

## 6. Cache Laravel

Dopo `.env`, database e storage:

```bash
php artisan optimize:clear
php artisan optimize
```

Ripetere dopo ogni aggiornamento. Se cambia solo una view, eseguire almeno `php artisan view:clear && php artisan view:cache`.

## 7. Cron e scheduler

Configurare in cPanel:

```cron
* * * * * cd /home/account/francoach && /usr/bin/php artisan schedule:run >> /home/account/francoach/storage/logs/scheduler.log 2>&1
```

Lo scheduler gestisce promemoria e backup giornaliero alle 02:15, timezone `Europe/Rome`, con prevenzione sovrapposizioni. Controllare:

```bash
php artisan schedule:list
php artisan notifications:send-reminders
php artisan francoach:backup
```

## 8. E-mail

Usare SMTP autenticato del provider. Verificare mittente, TLS, SPF, DKIM e DMARC. Non usare driver `log` in produzione. Eseguire un reset password e controllare consegna e log senza esporre credenziali.

## 9. HTTPS e Apache

- installare certificato valido e rinnovo automatico;
- reindirizzare HTTP a HTTPS a livello hosting;
- lasciare `SESSION_SECURE_COOKIE=true`;
- abilitare `mod_rewrite` e `mod_headers`;
- impedire directory listing;
- non modificare la CSP senza riesaminare domini video e script;
- verificare `apachectl -t` quando disponibile.

## 10. PWA

Servire manifest, icone e service worker via HTTPS. Verificare installazione sia su dominio root sia in sottocartella; il manifest usa URL relativi. Le notifiche browser sono opzionali e richiedono consenso esplicito. Il sistema resta funzionante se browser, service worker o permessi notifiche non sono disponibili.

## 11. Log e monitoraggio

Controllare `storage/logs/laravel.log`, `notifications-scheduler.log`, `scheduler.log` e `backup-*.log`. Impedire accesso web, applicare rotazione del provider e non registrare segreti. Monitorare errori 5xx, spazio disco, scadenza certificato, esito cron e presenza backup.

## 12. Hosting senza SSH

1. Preparare localmente `vendor/` e `public/build/` con versioni PHP compatibili.
2. Caricare via SFTP, non FTP in chiaro.
3. Importare `database/schema/mysql-schema.sql` da phpMyAdmin.
4. Caricare temporaneamente `deployment/one-time-install.php.example` rinominandolo con nome casuale e `.php`.
5. Impostare `INSTALL_TOKEN` di almeno 64 caratteri e `INSTALL_ALLOWED_IP` nell’ambiente hosting.
6. Proteggere lo script anche con Basic Auth o protezione directory cPanel.
7. Richiamarlo una sola volta in `POST` via HTTPS con header `X-Install-Token`, per esempio da una macchina amministrativa: `curl -X POST -H "X-Install-Token: …" https://app.example.it/nome-casuale.php`.
8. Verificare esito generico, file lock e log Laravel.
9. Eliminare immediatamente script, token e protezione temporanea; verificare 404.
10. Configurare cron cPanel e storage come sopra.

Il template non è eseguibile finché conserva l’estensione `.example`. Non lasciare endpoint di installazione in produzione.

## 13. Aggiornamenti

1. creare e verificare un backup;
2. attivare manutenzione;
3. caricare release con strategia atomica se disponibile;
4. eseguire `composer install --no-dev`, migration e build preparata;
5. eseguire `php artisan optimize`;
6. disattivare manutenzione;
7. completare la checklist post-deploy;
8. conservare release e backup precedenti fino a collaudo concluso.

Non eseguire downgrade di migration distruttive. Ripristinare codice, database e file dallo stesso punto temporale.
