Servir una aplicación Laravel con Apache en Debian 13
verificado el 7 septiembre 2026 · 4 min
Tres condiciones para servir Laravel con Apache: DocumentRoot sobre la carpeta public/, sudo a2enmod rewrite y AllowOverride All sobre esa carpeta. Sin esta última directiva, Apache ignora el .htaccess que trae Laravel: la página de inicio se muestra, pero todas las demás rutas devuelven 404.
Apache sigue siendo el servidor web más extendido en el alojamiento compartido y en las máquinas que llevan años en producción. Servir una aplicación Laravel detrás de Apache exige tres cosas: un host virtual cuya raíz apunte a public/, el módulo de reescritura activado y AllowOverride All para que Apache lea el archivo .htaccess que trae Laravel.
Este capítulo forma parte de la instalación de Laravel en Debian, dentro del itinerario Desarrollo web. Olvidar ese tercer punto es la causa casi sistemática de las rutas que responden con un 404. Pasos verificados en Debian 13 con Apache 2.4.68 y Laravel 13.30.1.
Instalar Apache y el módulo PHP
sudo apt update
sudo apt install -y apache2 libapache2-mod-php
apache2 -vServer version: Apache/2.4.68 (Debian)El paquete libapache2-mod-php activa PHP dentro de Apache. Compruébalo:
a2query -m | grep phpphp8.4 (enabled by maintainer script)Activa después el módulo de reescritura, que no viene activo por defecto:
sudo a2enmod rewriteColocar el proyecto
Crea la aplicación con Composer, desde una cuenta sin privilegios:
su - deploy
composer create-project laravel/laravel /home/deploy/app --no-interaction
cd /home/deploy/app
php artisan --version # Laravel Framework 13.30.1Dé después permisos de escritura a las tres únicas carpetas que los necesitan, database/ incluida mientras la aplicación use la base SQLite creada en la instalación:
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 debe poder atravesar el directorio personalCrear el host virtual
<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>Activa el sitio, desactiva el que viene por defecto y comprueba la sintaxis:
sudo a2ensite laravel
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2Syntax OKAllowOverride All: la línea que lo decide todo
Laravel incluye un archivo public/.htaccess que redirige todas las peticiones a index.php. Apache solo lee ese archivo si la directiva AllowOverride se lo permite. Sin ella, la página de inicio se muestra, pero ninguna otra ruta responde.
El comportamiento se ha medido sobre la ruta de salud /up, presente en cualquier instalación reciente:
| Configuración | / | /up |
|---|---|---|
AllowOverride All y rewrite activo | 200 | 200 |
AllowOverride None | 200 | 404 |
Ese es el síntoma que hay que reconocer: la portada funciona y todo lo demás devuelve 404. El problema no está ni en las rutas ni en el código, sino en la configuración de Apache.
El comienzo del .htaccess que trae Laravel, del que depende todo este mecanismo:
<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}]Verificar la instalación
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 : 404El 404 en /.env es el resultado esperado: como la raíz del sitio es public/, el archivo queda fuera del árbol servido y sencillamente no es accesible. Si obtienes 200, es que DocumentRoot apunta a la raíz del proyecto en lugar de a public/, y tus credenciales de base de datos son públicamente legibles.
Pasar a HTTPS
Certbot modifica él mismo el host virtual e instala la renovación automática:
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d exemple.comAcuérdate de desactivar el modo de depuración y de alinear APP_URL con la dirección en HTTPS, si no, los enlaces y los assets que genera Laravel seguirán apuntando a 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 | |
|---|---|---|
| Ejecución de PHP | módulo integrado o PHP-FPM | solo PHP-FPM |
| Configuración por carpeta | sí, mediante .htaccess | no, todo en la configuración del sitio |
| Reescritura para Laravel | la trae Laravel | hay que escribirla en el bloque location |
| Alojamiento compartido | muy extendido | poco frecuente |
El .htaccess es la ventaja decisiva de Apache en alojamiento compartido: permite configurar la reescritura sin tocar la configuración del servidor. En una máquina que administras tú, ambos sirven, y la elección depende de cuál sepas explotar mejor.
Errores frecuentes
chmod o+x /home/deploy, si no, Apache devuelve un error de permisos.