Capitolo 4 di 5

Servire un’applicazione Laravel con Apache su Debian 13

verificato il 7 Settembre 2026 · 4 min

Risposta rapida

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

bash
sudo apt update
sudo apt install -y apache2 libapache2-mod-php
apache2 -v
code
Server version: Apache/2.4.68 (Debian)

Il pacchetto libapache2-mod-php attiva PHP dentro Apache. Verificalo:

bash
a2query -m | grep php
code
php8.4 (enabled by maintainer script)

Attiva poi il modulo di riscrittura, che non è abilitato di default:

bash
sudo a2enmod rewrite

Mettere il progetto al suo posto

Crea l’applicazione con Composer, da un account senza privilegi:

bash
su - deploy
composer create-project laravel/laravel /home/deploy/app --no-interaction
cd /home/deploy/app
php artisan --version   # Laravel Framework 13.30.1

Date 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:

bash
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 personale

Creare il virtual host

/etc/apache2/sites-available/laravel.conf
<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:

bash
sudo a2ensite laravel
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2
code
Syntax OK

AllowOverride 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:

public/.htaccess
<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

bash
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/.env
code
accueil : 200
route   : 200
.env    : 404

Il 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:

bash
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d exemple.com

Ricordati 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:

.env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://exemple.com
bash
php artisan config:cache
php artisan route:cache
php artisan view:cache

Apache 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

AllowOverride assente o impostato su None Apache ignora il .htaccess di Laravel. La home risponde, tutte le altre rotte danno 404. Sintomo misurato sulla rotta /up.
Dimenticare a2enmod rewrite Su Debian il modulo di riscrittura non è attivo di default. Stesso effetto del punto precedente.
DocumentRoot sulla radice del progetto Il file .env diventa scaricabile. Deve rispondere 404, prova che la radice è davvero public/.
Cartella personale non attraversabile Un progetto in /home/deploy richiede chmod o+x /home/deploy, altrimenti Apache restituisce un errore di permessi.
APP_URL rimasto in HTTP dopo Certbot I link e gli asset generati da Laravel continuano a puntare in HTTP.
Newsletter

I nuovi test, tutorial e progetti, via e-mail.

Test riproducibili, codice versionato, risultati datati. Mai spam.