Capítulo 4 de 5

Servir una aplicación Laravel con Apache en Debian 13

verificado el 7 septiembre 2026 · 4 min

Respuesta rápida

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

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

El paquete libapache2-mod-php activa PHP dentro de Apache. Compruébalo:

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

Activa después el módulo de reescritura, que no viene activo por defecto:

bash
sudo a2enmod rewrite

Colocar el proyecto

Crea la aplicación con Composer, desde una cuenta sin privilegios:

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

Dé 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:

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 debe poder atravesar el directorio personal

Crear el host virtual

/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>

Activa el sitio, desactiva el que viene por defecto y comprueba la sintaxis:

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

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

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}]

Verificar la instalación

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

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

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

Acué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:

.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
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

AllowOverride ausente o en None Apache ignora el .htaccess de Laravel. La portada responde, todas las demás rutas devuelven 404. Síntoma medido sobre la ruta /up.
Olvidar a2enmod rewrite El módulo de reescritura no viene activo por defecto en Debian. Mismo efecto que el anterior.
DocumentRoot sobre la raíz del proyecto El archivo .env pasa a ser descargable. Debe devolver 404, lo que demuestra que la raíz es realmente public/.
Directorio personal no atravesable Un proyecto en /home/deploy exige chmod o+x /home/deploy, si no, Apache devuelve un error de permisos.
APP_URL sin actualizar tras Certbot Los enlaces y los assets que genera Laravel siguen apuntando a HTTP.
Newsletter

Las nuevas pruebas, tutoriales y proyectos, por correo.

Pruebas reproducibles, código versionado, resultados fechados. Nunca spam.