Cómo configurar bien Apache para las aplicaciones Symfony2
<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>
¿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.