() translation by (you can also view the original English article)
Los requerimientos de desempeño de WordPress pueden variar entre proyectos, pero una cosa ciertamente permanece a lo largo---debe ser rápido.
Otro requerimiento que va sin decirlo---debe ser económico, así que no podemos tener soluciones intensivas de recursos. Las soluciones deben ser ligeras, a la medida y confiables, y para maximizar completamente el ingreso en tu sitio, el gasto de hospedaje debe ser mantenido al mínimo.
Si estás esperando recibir mucho tráfico, la configuración del servidor web sobre el que estás sirviendo WordPress tiene un efecto directo sobre el desempeño de tu sitio, afectando el tiempo de carga y la estabilidad.
Cuando eliges tu servidor web, tienes varias opciones; Apache, Nginx, IIS, Caddy, y Lighttpd son todos proyectos populares. Estaremos cubriendo Apache y Nginx en esta guía.
Es estimado que de todo el internet combinaod, Apache Server y Nginx juntos sirven el 50% de todo el tráfico web.
Si eres un principiante en el tema, tal vez estás confundido por los dos propósitos aparentemente idénticos del software---servir sitios web. Espero clarificar más abajo sobre cómo difieren los dos y cómo sacar ventaja de las características de ambos.
Apache y Nginx son proyectos muy establecidos, y ambos tienen sus propias razones de ser así que mientras que logran una meta similar idéntica de servir tu sitio WordPress. Sin embargo, cuando vemos más a fondo sus diseños, hay una diferencia mayor sobre cómo manejan las conexiones cada servidor.
La Diferencia
Una diferencia mayor está en cómo las conexiones son manejadas por ambos.
Puesto de manera simple, Apache usa una solución apuntalada, o de mantener vivo, la cuál mantiene una conexión abierta para cada usuario.
Por otro lado, Nginx usa un ciclo de evento sin bloqueo, la cuál junta conexiones funcionando de manera asíncrona vía procesos de trabajo.



Debido a esta arquitectura, el resultado es un proceso nginx de un solo hilo, y no se generan procesos adicionales para manejar cada nueva conexión. Así que incluso en momentos de carga alta, el CPU y la RAM no se enlatan en esta aproximación.
Así como arquitectura, también hay algunas ligeras diferencias y marices entre los dos en configuración, y recorreremos estos a más detalle después en esta guía.
Primero, echemos un vistazo a los dos proyectos y obtengamos una vista general clara.
Apache
- Comenzado en 1995 por Robert McCool, un alumno de la Universidad de Illinois, desarrollado continuamente bajo la Fundación de Software Apache desde 1999.
- Más ampliamente en el Internet desde 1996 (por defecto para muchos anfitriones ej. usuarios cPanel).
- Usa un sistema de carga de módulo dinámico ampliamente extensible.
- Usa un archivo
.htaccess
para re-escritura de URL. - Usa un archivo
httpd.conf
para Configuración de Servidor con sintaxis como XML.
WordPress trabaja con Apache prácticamente salido de la caja. Un módulo PHP tal como mod_php
es requerido, pero no hay mucho más que se necesite para que funcione.
Apache es muy flexible y tiene muchos módulos. Comúnmente, mod_rewrite
es usado para proporcionar re-escritura URL para interpretar URLs tales como categories.php?id=4
a /categories/4
.
Nginx
- Iniciado en 2002 por Igor Sysoev, un ingeniero de software Ruso, como una solución al problema C10k---un reto para servidores web para manejar 10,000 conexiones concurrentes.
- Liberado públicamente en 2004, cumpliendo la meta como una arquitectura asíncrona, sin bloqueo y manejada por evento.
- Ligera de ejecución en hardware mínimo proporciona excelente rendimiento de contenido estático.
- Altamente responsivo bajo carga pesada.
- Usa un archivo de configuración
nginx.conf
con una sintaxis de llave como JS. - Extensible con módulos de terceros.
Como un sucesor de Apache, Nginx tiene el beneficio de conocer las trampas y problemas de desempeño de concurrencia que pueden ocurrir, y este recoge las recompensas completas de esto con su muy rápido diseño de ciclo de evento asíncrono.
Para contenido estático esto trabaja muy rápido. Así como para contenido dinámico, como PHP por ejemplo, Nginx no tiene la habilidad de procesar esto con un módulo como lo hace Apache. Pero esto no es un obstáculo, ya que usa FastCGI para lograr esto. Esto funciona muy bien en conjunto con piletas de conexión php fpm y caché de memoria.
Requerimientos WordPress
- PHP 7 >
- MySQL 5.6 o Maria DB 10.0 >
- mod_rewrite (si se usa Apache)
- SSL (si se usa)
Tanto Apache como Nginx soportan php fpm. Este es un administrador de FastCGI, un administrador de procesos bifurcados para PHP el cuál puede ser usado para proporcionar un tiempo de respuesta muy rápido. Ejecutándose como un daemon sobre el servidor, generará procesos de manera nativa mientras son requeridos.
Configurando PHP FPM Con Apache
Los usuarios Ubuntu y Debian pueden instalar los paquetes requeridos con aptitude vía:
1 |
sudo apt-get -y install libapache2-mod-fastcgi php7.0-fpm php7.0 |
Ahora habilita el módulo en apache:
1 |
a2enmod actions fastcgi alias
|
Después, en el archivo de configuración /etc/apache2/conf-available/php7.0-fpm.conf
, agrega lo siguiente:
1 |
<IfModule mod_fastcgi.c> |
2 |
AddHandler php7-fcgi .php |
3 |
Action php7-fcgi /php7-fcgi |
4 |
Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi |
5 |
FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi -socket /var/run/php/php7.0-fpm.sock -pass-header Authorization |
6 |
</IfModule>
|
También, en tu VirtualHost para WordPress (ruta por defecto /etc/apache2/sites-available/000-default.conf
), agrega lo siguiente:
1 |
<Directory /usr/lib/cgi-bin> |
2 |
Require all granted |
3 |
</Directory>
|
4 |
<IfModule mod_fastcgi.c> |
5 |
SetHandler php7-fcgi .php |
6 |
Action php7-fcgi /php7-fcgi virtual |
7 |
Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi |
8 |
FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi -socket /var/run/php/php7.0-fpm.sock -pass-header Authorization |
9 |
</IfModule>
|
Ahora reinicia apache y estás listo para seguir
1 |
systemctl restart apache2.service |
Haz un archivo <?php phpinfo(); ?>
y mira en tu navegador. PHP ahora estará sirviendo como FPM.
Ahora revisa tu blog WordPress. ¿Notas alguna diferencia?
Configurando PHP FPM Con Nginx
Los usuarios Ubuntu y Debian pueden instalar el paquete con lo siguiente:
1 |
apt-get -y install php7.0-fpm |
Ahora, dentro de tu archivo de configuración (default /etc/nginx/sites-available/default) en el bloque del servidor, necesitas agregar la configuración FastCGI como sigue:
1 |
server { |
2 |
... |
3 |
location / { |
4 |
# use try files to try and serve the file |
5 |
try_files $uri $uri/ =404; |
6 |
} |
7 |
|
8 |
# PHP FPM Configuration |
9 |
location ~ \.php$ { |
10 |
include snippets/fastcgi-php.conf; |
11 |
|
12 |
# Connect via socket |
13 |
fastcgi_pass unix:/run/php/php7.0-fpm.sock; |
14 |
} |
15 |
|
16 |
# deny apache .htaccess requests |
17 |
location ~ /\.ht { |
18 |
deny all; |
19 |
} |
20 |
... |
21 |
} |
Aquí usamos el snippet de Nginx para establecer los parámetros cgi y pasar a fastcgi el socket de conexión.
Después, asegúrate de que estableces el cgi.fix_pathinfo=0
en el php ini, ya que el ajuste por defecto está rompiendo la configuración. Edita /etc/php/7.0/fpm/php.ini
y establece:
1 |
[...] |
2 |
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's |
3 |
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok |
4 |
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting |
5 |
; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting |
6 |
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts |
7 |
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. |
8 |
; https://php.net/cgi.fix-pathinfo |
9 |
cgi.fix_pathinfo=0 |
10 |
[...] |
Ahora puedes guardar el archivo, y recargar PHP FPM. Haz esto vía:
1 |
service php7.0-fpm reload |
Finalmente, podemos revisar el <?php phpinfo(); ?>
en un navegador para confirmar que el servidor está usando ahora PHP FPM con Nginx.
Haciendo mod_rewrite en Nginx
Nginx no usa un archivo .htaccess
, y para re-escritura URL tiene una aproximación mucho más simple.
Para hacer que tu blog WordPress funcione con Nginx, simplemente agrega lo siguiente a la parte try_files
de tu configuración Nginx:
1 |
location / { |
2 |
index index.php index.html index.htm; |
3 |
try_files $uri $uri/ /index.php?q=$uri&$args; |
4 |
} |
Si estás usando un directorio para tu blog WordPress, por favor establece lo siguiente:
1 |
location /wordpress/ { |
2 |
try_files $uri $uri/ /index.php?q=$uri&$args; |
3 |
} |
Reinicia Nginx y tendrás funcionando re-escritura URL.
1 |
$ service nginx restart
|
Configuraciones Óptimas
Tienes muchas opciones para optimizar WordPress vía cacheando en el servidor vía memcache, varnish y también en el nivel de app WordPress con complementos que te permitirán acceder fácilmente a esto.
Sin embargo, lo que te da Nginx es una gran solución para servir contenido web estático con su robusta y rápida caché de contenido estático.
Caché de Contenido Estático
Nginx es muy rápido cuando se usa como un caché de contenido estático, y es aquí en donde su uso realmente sobresale en términos de WordPress y publicaciones con muchas imágenes. Puedes servir tu CSS, JS e imágenes todo vía un servidor Nginx ejecutándose solo para estas necesidades.
Siempre es mejor hacer esto en un dominio sin cookies para que el contenido sea realmente cacheado por el navegador (ya que la cookie no es cacheable), así que usar un sub-dominio tal como images.myblog.com
o static.myblog.com
sería ideal.
Un bloque de ubicación para estos sub-dominios estáticos de configuración debería lucir así:
1 |
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|svg)$ { |
2 |
access_log off; |
3 |
expires 30d; |
4 |
tcp_nodelay off; |
5 |
## Set the OS file cache. |
6 |
open_file_cache max=3000 inactive=120s; |
7 |
open_file_cache_valid 45s; |
8 |
open_file_cache_min_uses 2; |
9 |
open_file_cache_errors off; |
10 |
} |
Usando open_file_cache
, habilitamos el cacheo para nuestros archivos de medios estáticos. Especificamos el máximo de archivos a cachear y por cuánto tiempo con open_file_cache max=3000 inactive=120s;
si quieres configurar el cacheo en todo el proyecto, solo agrega las siguientes cuatro líneas en tus configuraciones nginx.conf:
1 |
open_file_cache max=10000 inactive=5m; |
2 |
open_file_cache_valid 2m; |
3 |
open_file_cache_min_uses 1; |
4 |
open_file_cache_errors on; |
Importante: El open_file_cache_errors
cacheará los errores 404 actuales, así que es mejor apagar esto si estás usando un balanceador de carga en conjunto con esto.
Pilas de Conexión PHP-FPM
Es posible usar diferentes pilas para cada WordPress diferente, y puedes después colocar recursos muy precisamente para cada sitio---incluso usando diferentes usuarios y grupos para cada pila si se necesita. La configuración es muy flexible.
Puedes establecer varias configuraciones, por ejemplo:
1 |
/etc/php-fpm.d/family-site.conf |
2 |
/etc/php-fpm.d/travel-blog.conf |
3 |
/etc/php-fpm.d/cooking-recipes.conf |
En cada uno de los siguientes, podemos establecer una plétora de configuraciones como:
1 |
[site] |
2 |
listen = 127.0.0.1:9000 |
3 |
user = user |
4 |
group = websites |
5 |
request_slowlog_timeout = 5s |
6 |
slowlog = /var/log/php-fpm/slowlog-site.log |
7 |
listen.allowed_clients = 127.0.0.1 |
8 |
pm = dynamic |
9 |
pm.max_children = 5 |
10 |
pm.start_servers = 3 |
11 |
pm.min_spare_servers = 2 |
12 |
pm.max_spare_servers = 4 |
13 |
pm.max_requests = 200 |
14 |
listen.backlog = -1 |
15 |
pm.status_path = /status |
16 |
request_terminate_timeout = 120s |
17 |
rlimit_files = 131072 |
18 |
rlimit_core = unlimited |
19 |
catch_workers_output = yes |
20 |
env[HOSTNAME] = $HOSTNAME |
21 |
env[TMP] = /tmp |
22 |
env[TMPDIR] = /tmp |
23 |
env[TEMP] = /tmp |
Con esto, puedes especificar las opciones de configuración PHP-FPM tales como pm.max_children, y también puedes especificar variables ambientales y establecer los ajustes de nombre de usuario y grupo aquí.
Balanceador de Carga Nginx
Si vas a tener mucho tráfico entonces probablemente querrás establecer un balanceador de carga para usar con tu configuración php-fpm.
Convencionalmente, querremos iniciar varios servidores de río arriba back-end, de los cuáles todos están ejecutando espejos de tu blog, y después tener otro servidor ejecutando nginx en frente de este el cuál está actuando como un balanceador de carga y dirigirá la carga entre los flujos.
Esto significa que puedes usar muchos servidores para alimentar tu blog de una vez, y la configuración para hacerlo es relativamente sencilla.
Un ejemplo de configuración luciría como esto. Primero comenzamos con un módulo río arriba:
1 |
upstream backend { |
2 |
server backend1.example.com; |
3 |
server backend2.example.com; |
4 |
server backend3.example.com; |
5 |
} |
Aquí, cada backend1.example.com tiene su propia configuración Nginx, un espejo de cómo el sitio estaba antes de que tuviera un balanceador de carga. Nginx elegirá cuál servidor usar para cada petición.
Si uno de nuestros back ends tiene un disco duro más rápido, como SSD por ejemplo, o si está geográficamente más cercano a tu base principal de usuarios, puedes establecer ponderación así:
1 |
upstream backend { |
2 |
server backend1.example.com weight=1; |
3 |
server backend2.example.com weight=2; |
4 |
server backend3.example.com weight=4; |
5 |
} |
De manera adicional, si crees que un servidor podría venirse abajo o estás preocupado por tiempos fuera, también hay opciones de configuración para esto:
1 |
upstream backend { |
2 |
server backend1.example.com max_fails=3 fail_timeout=15s; |
3 |
server backend2.example.com weight=2; |
4 |
server backend3.example.com weight=4; |
Ahora, con esta configuración, después de tres fallos o un tiempo de espera de 15 segundos, el servidor y ano será usado por el balanceador de carga. Si deseas marcar manualmente un servidor como inactivo, agrega la palabra clave down
, ej. server backend3.example.com down
;.
Después necesitamos pasar eso al servidor vía proxy usando el flujo backend
que acabamos de definir:
1 |
server { |
2 |
location / { |
3 |
proxy_pass http://backend; |
4 |
} |
5 |
} |
Ahora reinicia tu servidor con service nginx restart
, ¡y estás ejecutando una versión de carga balanceada de tu sitio!
Por último en este tema, también para tu referencia aquí está una guía nginx sobre servir contenido estático y las mejores opciones de configuración. Toma nota de usar tcp_nopush
y sendfile
para Mp3, por ejemplo.
Migrando Apache a Nginx
Además de leer el manual Nginx y probar hacer los cambios tu mismo, puedes usar la herramienta de código abierto apache2nginx para traducir tu configuración desde Apache hasta Nginx.
Sigue los pasos de instalación en el LÉEME apache2nginx, y una vez instalado tendrás la habilidad de migrar archivos de configuración simplemente ejecutando:
1 |
$ apache2nginx -f /etc/httpd/conf/httpd.conf |
Ahora puedes revisar la configuración y probarla en tu instalación Nginx. Podrías encontrar que la traducción no fue perfecta, pero te dará una base sobre la cuál comenzar.
Conclusión
Para velocidad y rendimiento, Nginx es la elección obvia sobre Apache, pero eso no es decir que Apache no puede manejar algo de tráfico. Si estás planeando ir a la página principal de Reddit pronto, probablemente deberías buscar una solución más pesada con Nginx y PHP-FPM.
Migrar tu WordPress a Nginx no es muy difícil, y la configuración yendo en Nginx es muy sencilla y fácil para acceder en comparación con la de Apache.
Aunque no hay los mismos módulos que en Apache, y podría no ser familiar al principio, podrás encontrar un reemplazo en la mayoría de los casos. Si no, como una solución, siempre puedes hacer proxy al antiguo servidor vía tu nginx para este propósito si es necesario.
Hay muchas maneras de configurar ambos servidores, así que una buena solución puede ser casi siempre encontrada para lo que sea que necesiten los requerimientos. Por ahora, parece que Apache siempre será la opción por defecto en el software de hospedaje cPanel ampliamente disponible, debido a la herramienta de configuración EasyApache que viene con este.
En el futuro, probablemente más anfitriones adoptarán herramientas cPanel Nginx como Engitron que proporciona Nginx en cPanel también.
Por ahora, si deseas cambiar a un WordPress alimentado por Nginx, necesitarás establecer una VPN Linux en DigitalOcean, AWS, u otro proveedor de hospedaje.