Servire un’applicazione Laravel con Apache su Debian 13
verificato il 7 Settembre 2026 · 4 min
Tre condizioni per servire Laravel con Apache: DocumentRoot sulla cartella public/, sudo a2enmod rewrite e AllowOverride All su quella cartella. Senza quest'ultima direttiva Apache ignora il .htaccess fornito da Laravel: la home page si vede, ma tutte le altre rotte rispondono 404.
Apache resta il server web più diffuso sull’hosting condiviso e sulle macchine in servizio da anni. Servire un’applicazione Laravel dietro Apache richiede tre cose: un virtual host la cui document root punta a public/, il modulo di riscrittura attivo e AllowOverride All, perché il file .htaccess fornito da Laravel venga davvero letto.
Questo capitolo fa parte dell’installazione di Laravel su un server Debian, nel percorso Sviluppo web. Dimenticare il terzo punto è la causa quasi sistematica delle rotte in errore 404. Passaggi verificati su Debian 13 con Apache 2.4.68 e Laravel 13.30.1.
Installare Apache e il modulo PHP
sudo apt update
sudo apt install -y apache2 libapache2-mod-php
apache2 -vServer version: Apache/2.4.68 (Debian)Il pacchetto libapache2-mod-php attiva PHP dentro Apache. Verificalo:
a2query -m | grep phpphp8.4 (enabled by maintainer script)Attiva poi il modulo di riscrittura, che non è abilitato di default:
sudo a2enmod rewriteMettere il progetto al suo posto
Crea l’applicazione con Composer, da un account senza privilegi:
su - deploy
composer create-project laravel/laravel /home/deploy/app --no-interaction
cd /home/deploy/app
php artisan --version # Laravel Framework 13.30.1Date poi i diritti di scrittura alle sole tre cartelle che ne hanno bisogno, database/ compresa finché l’applicazione usa il database SQLite creato all’installazione:
sudo chown -R deploy:www-data /home/deploy/app/storage /home/deploy/app/bootstrap/cache /home/deploy/app/database
sudo chmod -R 775 /home/deploy/app/storage /home/deploy/app/bootstrap/cache /home/deploy/app/database
sudo chmod o+x /home/deploy # Apache deve poter attraversare la cartella personaleCreare il virtual host
<VirtualHost *:80>
ServerName exemple.com
DocumentRoot /home/deploy/app/public
<Directory /home/deploy/app/public>
AllowOverride All
Require all granted
Options -Indexes +FollowSymLinks
</Directory>
ErrorLog ${APACHE_LOG_DIR}/laravel-error.log
CustomLog ${APACHE_LOG_DIR}/laravel-access.log combined
</VirtualHost>Attiva il sito, disattiva quello predefinito, controlla la sintassi:
sudo a2ensite laravel
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2Syntax OKAllowOverride All: la riga che decide tutto
Laravel fornisce un file public/.htaccess che dirotta ogni richiesta verso index.php. Apache legge quel file solo se la direttiva AllowOverride glielo consente. Senza di essa la home page si vede, ma nessun’altra rotta risponde.
Il comportamento è stato misurato sulla rotta di health check /up, presente in ogni installazione recente:
| Configurazione | / | /up |
|---|---|---|
AllowOverride All e rewrite attivo | 200 | 200 |
AllowOverride None | 200 | 404 |
È il sintomo da riconoscere: la home funziona, tutto il resto risponde 404. Il problema non è nelle rotte né nel codice, ma nella configurazione di Apache.
L’inizio del .htaccess fornito da Laravel, da cui dipende tutto questo meccanismo:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle X-XSRF-Token Header
RewriteCond %{HTTP:x-xsrf-token} .
RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]Verificare l’installazione
curl -s -o /dev/null -w "accueil : %{http_code}\n" http://127.0.0.1/
curl -s -o /dev/null -w "route : %{http_code}\n" http://127.0.0.1/up
curl -s -o /dev/null -w ".env : %{http_code}\n" http://127.0.0.1/.envaccueil : 200
route : 200
.env : 404Il 404 su /.env è il risultato atteso: dato che la radice del sito è public/, il file si trova fuori dall’albero servito e semplicemente non è raggiungibile. Se ottieni 200, significa che DocumentRoot punta alla radice del progetto invece che a public/, e le credenziali del database sono leggibili da chiunque.
Passare a HTTPS
Certbot modifica da sé il virtual host e imposta il rinnovo automatico:
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d exemple.comRicordati di disattivare la modalità di debug e di allineare APP_URL all’indirizzo in HTTPS, altrimenti i link e gli asset generati da Laravel continueranno a puntare in HTTP:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://exemple.comphp artisan config:cache
php artisan route:cache
php artisan view:cacheApache o nginx
| Apache | nginx | |
|---|---|---|
| Esecuzione di PHP | modulo integrato o PHP-FPM | solo PHP-FPM |
| Configurazione per cartella | sì, tramite .htaccess | no, tutto nella configurazione del sito |
| Riscrittura per Laravel | fornita da Laravel | da scrivere nel blocco location |
| Hosting condiviso | molto diffuso | raro |
Il .htaccess è il vantaggio decisivo di Apache sull’hosting condiviso: permette di configurare la riscrittura senza accesso alla configurazione del server. Su una macchina che amministri tu vanno bene entrambi, e la scelta dipende da quello che sai far girare.
Errori frequenti
chmod o+x /home/deploy, altrimenti Apache restituisce un errore di permessi.