Cómo configurar bien Apache para las aplicaciones Symfony2

Cambia los siguientes valores para adaptarlos a tu aplicación

<VirtualHost *:80>
    ServerName      mi-sitio.com
    ServerAlias     www.mi-sitio.com

    SetEnv SYMFONY__DATABASE__USER     "..."
    SetEnv SYMFONY__DATABASE__PASSWORD "..."

    DocumentRoot    "/Proyectos/Symfony2/mi-sitio.com/web"
    DirectoryIndex  app.php

    <Directory "/Proyectos/Symfony2/mi-sitio.com/web">
        AllowOverride None
        Allow from All

        <IfModule mod_rewrite.c>
            Options -MultiViews
            RewriteEngine On
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*)$ app.php [QSA,L]
        </IfModule>
    </Directory>

    CustomLog  /var/log/httpd/mi-sitio.com-access.log combined

    KeepAlive            On
    MaxKeepAliveRequests 200
    KeepAliveTimeout     5

    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/rss+xml" \
                                      "application/x-javascript" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "image/svg+xml" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/xml"
    </IfModule>

    <IfModule mod_headers.c>
        Header append Vary User-Agent env=!dont-vary

        ExpiresActive On
        ExpiresDefault "now plus 1 week"
        ExpiresByType image/x-icon "now plus 1 month"
        ExpiresByType image/gif    "now plus 1 month"
        ExpiresByType image/png    "now plus 1 month"
        ExpiresByType image/jpeg   "now plus 1 month"
    </IfModule>
</VirtualHost>

Además de esta configuración, asegúrate de que Apache tiene activados los módulos headers, expires, deflate y rewrite. Los tres primeros son deseables para mejorar el rendimiento de Symfony2, pero el último (mod_rewrite) es totalmente obligatorio. Para ello, añade o descomenta las dos siguientes líneas en el archivo principal de configuración de Apache:

LoadModule headers_module modules/mod_headers.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so

A continuación se explica el significado de cada opción de configuración y las razones por las que consideramos que esta es la mejor configuración para ejecutar aplicaciones Symfony2 en producción a través de Apache.

Datos básicos

ServerName      mi-sitio.com
ServerAlias     www.mi-sitio.com

El valor de la opción ServerName es lo que tienen que escribir los usuarios en la barra de direcciones de sus navegadores para acceder a tu sitio. A su vez, la opción ServerAlias indica los otros nombres que también se pueden utilizar para acceder a tu sitio. No olvides añadir aquí el dominio con las www por delante para que funcionen las dos variantes (con y sin www). Si quieres, puedes añadir más de un ServerAlias:

ServerName      mi-sitio.com
ServerAlias     www.mi-sitio.com www2.mi-sitio.com www3.mi-sitio.com

Variables de entorno

SetEnv SYMFONY__DATABASE__USER     "..."
SetEnv SYMFONY__DATABASE__PASSWORD "..."

Establecer variables de entorno directamente desde el archivo de configuración de Apache es una buena práctica recomendada para que no tengas que escribir el valor de las contraseñas ni en el archivo app/config/parameters.yml ni en app/config/config.yml ni en ningún otro archivo de configuración de Symfony2.

Para ello sólo debes utilizar la directiva SetEnv de Apache para crear variables cuyo nombre comience por SYMFONY__ (con dos guiones bajos). Después, escribe el nombre del parámetro que quieras establecer en el contenedor de servicios de Symfony2 (sustituyendo cada punto con dos guiones bajos).

De esta forma, la variable de entorno SYMFONY__DATABASE__USER se interpreta como el parámetro database.user de Symfony2 y la variable SYMFONY__DATABASE__PASSWORD se interpreta como database.password

Aunque esta técnica se utiliza principalmente para no escribir en los archivos de configuración ni contraseñas ni otros valores sensibles (como por ejemplo claves de APIs), también puedes utilizarla para establecer cualquier parámetro de configuración de Symfony2.

Si piensas que escribir las contraseñas en el archivo de configuración de Apache tampoco es seguro, puedes eliminar las directivas SetEnv anteriores y sustituirlas por lo siguiente:

Include  "/Directorio/Secreto/MiProyecto/Passwords.conf"

Después, solo tienes que crear ese archivo y añadir lo siguiente como su contenido:

SetEnv SYMFONY__DATABASE__USER     "..."
SetEnv SYMFONY__DATABASE__PASSWORD "..."

Directorio del proyecto

DocumentRoot    "/Proyectos/Symfony2/mi-sitio.com/web"

La opción DocumentRoot siempre debe apuntar al directorio web/ del proyecto Symfony2, ya que este es el único directorio público de las aplicaciones Symfony2.

DirectoryIndex  app.php

Apache por defecto busca un archivo llamado index.php o index.html dentro del directorio configurado en DocumentRoot. Sin embargo, en las aplicaciones Symfony2 no existe este archivo porque el controlador frontal se llama app.php. Utiliza la opción DirectoryIndex para indicar a Apache el archivo que debe buscar.

<Directory "/Proyectos/Symfony2/mi-sitio.com/web">
    AllowOverride None
    Allow from All

    <IfModule mod_rewrite.c>
        Options -MultiViews
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ app.php [QSA,L]
    </IfModule>
</Directory>

Este último bloque incluye la configuración del archivo .htaccess creado por Symfony2. Pasar esta información al archivo de configuración de Apache permite establecer la opción AllowOverride a None. Esto significa que Apache no va a buscar archivos llamados .htaccess en ninguno de los directorios del DocumentRoot, lo que ayuda a mejorar el rendimiento.

Archivo de log

CustomLog  /var/log/httpd/mi-sitio.com-access.log combined

La opción CustomLog indica el archivo donde se guardan todos los mensajes de log relacionados con este VirtualHost y también su formato. Resulta interesante utilizar un archivo de log propio para cada sitio, aunque el primer archivo que debes mirar en caso de error en el servidor de producción siempre es app/logs/prod.log.

Rendimiento

KeepAlive            On
MaxKeepAliveRequests 200
KeepAliveTimeout     5

Activa la opción Keep Alive de HTTP 1.1 para que las conexiones permanezcan abiertas después de entregar los contenidos al usuario. Por defecto, cuando un usuario solicita una página, el servidor cierra la conexión después de enviarle el contenido HTML, aunque después haya que abrir nuevas conexiones para servir los archivos CSS, JavaScript y las imágenes.

Activando la opción Keep Alive, el usuario puede realizar muchas peticiones reutilizando la misma conexión, lo que mejora notablemente el rendimiento que percibe el usuario en su navegador. La opción MaxKeepAliveRequests indica cuántas peticiones como máximo puede realizar un usuario sin que se le cierre la conexión. La opción KeepAliveTimeout indica cuántos segundos espera el servidor desde la última solicitud del usuario antes de cerrar su conexión.

¿Qué valores son los más adecuados para las opciones KeepAlive? Depende de cómo sea tu sitio y la cantidad de memoria RAM que dispongas. Comienza con valores razonables (no más de 5 para KeepAliveTimeout y no más de 100 para MaxKeepAliveRequests) y comprueba el rendimiento de tu servidor (sobre todo su consumo de memoria). Después, aumenta progresivamente el valor de MaxKeepAliveRequests vigilando de cerca el consumo de memoria de tu servidor.

AddOutputFilterByType DEFLATE text/css text/plain text/html application/xhtml+xml text/xml application/xml
 
<IfModule mod_headers.c>
    Header append Vary User-Agent env=!dont-vary
</IfModule>

La opción AddOutputFilterByType hace que el servidor comprima automáticamente el contenido de los tipos de archivos indicados (HTML, XML y CSS) antes de entregarlos al usuario. La penalización en el rendimiento (por tener que comprimir los contenidos) es mínima frente al enorme ahorro de ancho de banda conseguido (en ocasiones los contenidos de texto se comprimen hasta el 90%).

La cabecera Vary es imprescindible para que los posibles proxys que haya entre tu servidor y tus usuarios tengan en cuenta que algunos navegadores no soportan la compresión de contenidos y por tanto, no puede servir el mismo contenido a todos los usuarios (dependerá del navegador de cada usuario).

<IfModule mod_headers.c>
    ExpiresActive On
    ExpiresDefault "now plus 1 week"
    ExpiresByType image/x-icon "now plus 1 month"
    ExpiresByType image/gif    "now plus 1 month"
    ExpiresByType image/png    "now plus 1 month"
    ExpiresByType image/jpeg   "now plus 1 month"
</IfModule>

La opción ExpiresActive activa la cabecera Expires de HTTP para indicar la fecha de caducidad de los contenidos entregados al usuario. De esta forma, el navegador puede decidir si solicita el contenido al servidor o reutiliza el que ya tiene en la cache, por lo que el rendimiento que percibe el usuario mejora enormemente.

La configuración anterior indica que todos los contenidos servidos (por ejemplo archivos CSS y JavaScript) tienen un tiempo de vida de una semana, salvo las imágenes, a las que se les da un tiempo de vida de un mes.

Apache también permite indicar el tiempo de vida respecto a la fecha de modificación más reciente del contenido. Para ello, modifica now por modification:

<IfModule mod_headers.c>
    ExpiresActive On
    ExpiresDefault "modification plus 1 week"
    ExpiresByType image/x-icon "modification plus 1 month"
    ExpiresByType image/gif    "modification plus 1 month"
    ExpiresByType image/png    "modification plus 1 month"
    ExpiresByType image/jpeg   "modification plus 1 month"
</IfModule>

Compartir en

¿Has visto algún error?

Avísanos en [email protected] para que podamos corregirlo. Gracias.

Proyectos Symfony destacados

La forma más sencilla de generar el backend de tus aplicaciones Symfony. Ver más

Síguenos en @symfony_es para acceder a las últimas noticias.