Recientemente cambié el hosting del sitio web de un shared hosting a un VPS. La verdad no tenía intensiones de pagar una alta suma de dinero, lo que significa que la opción de VPS debía tener una cantidad relativamente baja de RAM, en mi caso 512Mb que aunque suene poco con los costos actuales de los módulos de memoria, es suficiente para mantener funcionando un servidor web, con su respectiva base de datos y algunos servicios adicionales. Si usas LAMP los procesos que consumen más memoria son mysql y apache2. Adicionalmente apache utiliza MPM prefork para php. Prefork es la mejor solución para aislar cada petición que se realiza al servidor web brindando más estabilidad. Pero al mismo tiempo, al crearse una copia del proceso padre se duplica el uso de memoria y es común que se usen varios procesos hijos precargados para mejorar la respuesta del servidor. Esto me conduce al propósito de este artículo…
Migrando apache al servidor web nginx
El VPS corre Ubuntu Server por lo que el proceso de configuración aplica para Ubuntu.
Instalar nginx
La instalación es tan sencilla como ejecutar el siguiente comando
sudo apt-get install nginx |
Nginx y php
Para que funcione con php necesitamos una interfaz FastCGI, para esto instalamos php5 FPM server. En apache, mod_php maneja las peticiones de php, lo que hace esencialmente es cargar todo php y las bibliotecas requeridas por cada petición de alguna página php. PHP-FPM funciona como un servidor web de php y se mantiene corriendo permanentemente por lo que no se recarga con cada petición.
sudo apt-get install php5-fpm |
Por defecto, PHP-FPM está configurado para usar sockets TCP en lugar de sockets UNIX, para obtener mejores resultados es preferible utilizarlo con socket UNIX. Esto se hace editando el archivo /etc/php5/fpm/pool.d/www.conf
Se incluyen algunas otras variaciones a la configuración ya que para utilizar sockets UNIX basta con la primera línea.
listen = /var/run/php5-fpm.sock listen.allowed_clients = 127.0.0.1 listen.owner = www-data listen.group = www-data listen.mode = 0660 user = www-data group = www-data pm = static pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 500 |
Luego en el archivo de configuración de nginx que se encuentra en /etc/nginx/nginx.conf agregamos dentro de la sección http lo siguiente
upstream php { server unix:/var/run/php5-fpm.sock; } |
Reiniciar servicios PHP-FPM Y NGINX
Para hacer efectivos los cambios en la configuración se reinician los servicios modificados
sudo service php5-fpm restart sudo service nginx restart |
Es probable que debas detener apache porque ambos servidores trataran de usar el puerto 80.
Hecho esto solo queda probar la configuración. Esto lo hacemos utilizando alguna otra aplicación web que tengamos corriendo con apache o cualquier sitio que requiera apache y php. Lo vamos a probar configurando un host virtual con wordpress.
Configuración de servidor virtual nginx para wordpress
En nginx es posible hacer esto de manera similar a apache, hay un directorio sites-available para los sitios disponibles y otro llamado sites-enabled para los habilitados. Se puede crear entonces un archivo en /etc/nginx/sites-available/wordpress que contendrá la configuración necesaria.
server { ## Your website name goes here. server_name localhost; ## Your only path reference. root /var/www/wordpress; ## This should be in your http block and if it is, it's not needed here. index index.php; access_log /var/www/wordpress/access.log; error_log /var/www/wordpress/error.log; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location / { # This is cool because no php is touched for static content. # include the "?$args" part so non-default permalinks doesn't break when using query string try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini include fastcgi_params; fastcgi_intercept_errors on; fastcgi_pass php; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } } |
Algunas lineas se explican por si mismas pero vamos a analizar las mas relevantes
server_name
Es la forma de definir servidores virtuales, de esta manera el mismo servidor nginx puede albergar múltiples dominios. Indicamos un nombre estático, un dominio dominio.com o un subdominio sitio.dominio.com
root
La ruta en el directorio de archivos donde se encuentra el sitio
access_log y error_log
Nginx mantiene archivos de bitácora para accesos y para errores. Por defecto, en la dirección /var/log/nginx encuentras las bitácoras de todo el servidor, lo que quiere decir que guarda accesos y errores de cada sitio virtual. Agregando esas directrices en la configuración del sitio virtual del ejemplo se logra que el servidor guarde archivos separados de bitácora para este sitio en la dirección que se especifique.
location
Location aparece varias veces y esto es porque permite distintas configuraciones basado en el URI. Pueden ser strings literales o expresiones regulares. En el ejemplo se usa para cosas como evitar agregar a bitácoras las peticiones del favicon.ico, indicar cuando expiran los archivos estáticos y como deben manejarse los archivos de php.
Al final del proceso contamos con un servidor web nginx configurado para usar php5-fpm que a su vez funciona con sockets UNIX para un mejor rendimiento y una reducción en el uso de memoria RAM de nuestro servidor.