En entornos donde se utiliza Nginx como proxy inverso para WordPress, es fundamental controlar con precisión qué contenido se debe cachear y qué no. Esto evita servir contenido obsoleto, respeta sesiones de usuarios y mejora el rendimiento global del sitio.
En este artículo exploramos una configuración avanzada de Nginx para un dominio ficticio, que implementa:
- Control de caché basado en múltiples condiciones.
- Reglas específicas para tipos de contenido estático.
- Redirección forzada a HTTPS.
- Integración con Let's Encrypt.
- Encabezados informativos para debug y auditoría.
Estructura del Fichero
La configuración completa se muestra a continuación y será analizada por secciones:
map $request_method $is_post {
POST 1;
default 0;
}
map $query_string $has_query_string {
"" 0;
default 1;
}
map $request_uri $is_sensitive_uri {
~*"/wp-admin/|/back/|/xmlrpc.php|wp-.*\.php|index.php|.*sitemap.*\.(xml|xsl|html)|.*_ga.*|.*utm.*|.*gclid.*|.*fbclid.*|.*gdpr.*" 1;
default 0;
}
map $request_uri $is_excluded_js {
~*"^/recaptcha/api.js$|^/analytics.js$|^/gtag/js$|^/gtm.js$|^/tag/js/gpt.js$|^/dist/scripts/main.js$|^/assets/js/gdpr_cc_addon.js$|^/gdpr-cookie-compliance/dist/scripts/main.js$" 1;
default 0;
}
map "$is_post$has_query_string$is_sensitive_uri$is_excluded_js" $skip_cache {
"~*1" 1;
default 0;
}
server {
listen 443 ssl http2;
server_name ejemplo.com www.ejemplo.com;
ssl_certificate /etc/nginx/ssl/ejemplo.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/ejemplo.com/privkey.pem;
include /etc/nginx/ssl/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
access_log /var/log/nginx/ejemplo_access.log;
location / {
proxy_pass https://BACKEND_IP:PORT;
include /etc/nginx/proxy_params;
proxy_cache cache_zone_name;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
proxy_cache_valid 200 4h;
proxy_cache_revalidate on;
proxy_cache_background_update on;
proxy_cache_min_uses 1;
#proxy_ignore_headers Cache-Control Set-Cookie;
add_header X-Skip-Cache $skip_cache;
add_header X-Cache-Status $upstream_cache_status;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
expires off;
}
location ~* \.(pdf|ico|svg|jpg|jpeg|png|gif|webp|ogg|mp4|webm|css|js|ttf|woff|woff2|otf|eot|txt)$ {
proxy_pass https://BACKEND_IP:PORT;
include /etc/nginx/proxy_params;
proxy_cache cache_zone_name;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504 http_403 http_404;
proxy_cache_valid 200 12h;
proxy_cache_revalidate on;
proxy_cache_background_update on;
proxy_cache_min_uses 1;
add_header Cache-Control "public, max-age=31557600";
add_header X-Cache-Status $upstream_cache_status;
expires 1y;
}
}
server {
listen 80;
server_name ejemplo.com www.ejemplo.com;
return 301 https://ejemplo.com$request_uri;
}
Análisis por Componentes
1. map
para control de caché
Se establecen variables en función de:
- Método POST (
$is_post
): no cachear formularios u operaciones. - Cadena de consulta (
$has_query_string
): indica parámetros dinámicos (e.g., UTM). - URIs sensibles (
$is_sensitive_uri
): como/wp-admin/
,xmlrpc.php
o URLs confbclid
,gclid
,utm
, etc. - Scripts JS que no deben cachearse (
$is_excluded_js
).
Estas variables se combinan en $skip_cache
, que decide si se salta la caché:
map "$is_post$has_query_string$is_sensitive_uri$is_excluded_js" $skip_cache {
"~*1" 1;
default 0;
}
2. Bloque principal del servidor
Se define un server
en HTTPS con HTTP/2 y certificado Let's Encrypt.
3. location /
Para todo el tráfico general:
- Se aplica
proxy_cache
con clave$scheme$host$request_uri
. - Se evita cachear según la variable
$skip_cache
. - Se añaden encabezados como
X-Skip-Cache
yX-Cache-Status
para diagnóstico. - Se evita el uso de caché del navegador (
Cache-Control
+expires off
).
4. Archivos estáticos
Para extensiones como .jpg
, .css
, .js
, .woff2
, etc., se define:
- Cacheo agresivo: hasta 1 año (
max-age=31557600
). - Revalidación y actualización en segundo plano.
- Se permiten respuestas "stale" si hay errores en el origen.
5. Redirección HTTP → HTTPS
Se fuerza la navegación segura con redirección permanente (301).
Conclusión
Esta configuración de Nginx ofrece un excelente equilibrio entre rendimiento y precisión, especialmente para sitios WordPress detrás de un proxy inverso. El uso de map
permite aplicar reglas complejas sin comprometer la legibilidad ni la mantenibilidad. Además, los encabezados de diagnóstico ayudan a entender en tiempo real si una petición se sirvió desde la caché.
Este enfoque es ideal para arquitecturas modernas donde se prioriza tanto la velocidad como la personalización del contenido dinámico.