Cómo montar tu propia CDN para WordPress usando Varnish o Nginx (y no depender solo de terceros)

Quien administra WordPress a escala lo sabe: el problema ya no es solo el PHP o la base de datos, sino llevar contenido rápido a usuarios repartidos por medio planeta… sin que la factura de la CDN comercial se dispare ni tu infraestructura se convierta en una caja negra.

En los últimos años muchos proyectos han pasado de usar “un plugin de caché + CDN externa” a plantearse algo más ambicioso: montar su propia CDN, apoyándose en tecnologías abiertas como Varnish Cache o Nginx. No se trata de reinventar la rueda, sino de recuperar control: dónde se cachea, qué se cachea, cuánto tiempo y a qué coste.

Este artículo está pensado para una web de administradores de sistemas que gestionan uno o varios WordPress con tráfico serio (medios, e-commerce, SaaS, portales corporativos) y quieren entender cómo plantear una CDN propia con herramientas conocidas.


¿Por qué plantearse una CDN propia para WordPress?

El modelo clásico: plugin + CDN comercial

El patrón típico que llega a manos de un sysadmin suele ser:

  • WordPress con plugin de caché (WP Rocket, Flyingpress, W3TC, LiteSpeed Cache, etc.).
  • Otro plugin o ajuste que reescribe URLs estáticas (/wp-content/uploads/, CSS, JS) a un dominio de CDN.
  • Una CDN comercial (Cloudflare, Akamai, Fastly, etc.) que sirve esos contenidos desde su red.

Ventajas:

  • Puesta en marcha rápida.
  • Cero cambios en infraestructura propia.
  • Panel cómodo para el equipo de marketing o contenidos.

Inconvenientes cuando se escala:

  • Visibilidad limitada de qué pasa exactamente en el edge.
  • Reglas de caché condicionadas por lo que permita el panel.
  • Dificultad para adaptar políticas por tipo de sitio / país / cliente.
  • Costes crecientes a medida que suben los GB y las peticiones.

El modelo alternativo: aprovechar lo que ya sabes (Varnish y/o Nginx)

En casi cualquier stack de WordPress medianamente serio ya están estos ingredientes:

  • Nginx como proxy inverso / servidor web.
  • Varnish Cache como acelerador HTTP en entornos más exigentes.
  • Experiencia previa en balanceo, TLS, logs, Prometheus/Grafana, etc.

La idea de una CDN propia no es montar 100 PoPs como un hiperescala, sino:

  • Tener algunos puntos de presencia bien situados (por ejemplo, Europa + América).
  • Usar Varnish o Nginx como capa de caché HTTP en esos PoPs.
  • Controlar rutas, TTLs, purgas y reglas específicas para WordPress.
  • Seguir usando, si interesa, una CDN comercial como complemento, no como dependencia absoluta.

Arquitectura base: WordPress + reverse proxy + PoPs

Una arquitectura razonable para una CDN propia orientada a WordPress podría ser algo así:

  1. Capa de aplicación
    • Servidores WordPress (PHP-FPM) detrás de Nginx o Apache.
    • Base de datos (MySQL/MariaDB) y servicios auxiliares (Redis, object cache, etc.).
  2. Origin shield
    • Uno o varios nodos que actúan como “origen lógico” de la CDN.
    • Aquí puedes tener:
      • Nginx con proxy_cache.
      • O Varnish Cache delante de Nginx/Apache.
    • Esta capa protege a WordPress de picos y agrega lógica de caché común.
  3. PoPs (puntos de presencia)
    • Servidores cache en distintas regiones (por ejemplo, Madrid, Frankfurt, Nueva York).
    • También con Varnish o Nginx como reverse proxy caché.
    • Sirven HTML y estáticos al usuario final.
  4. Capa de entrada
    • GeoDNS, anycast o un balanceador global que dirija a cada usuario al PoP más cercano.
    • TLS, WAF, rate limiting, etc., según necesidades.
  5. WordPress integrado con la CDN
    • Plugins o código propio que hagan purgas selectivas.
    • Reescritura de URLs de estáticos donde sea necesario.
    • Estrategia clara de qué se cachea y qué no.

Varnish vs Nginx como motor de caché en la CDN

Ambas herramientas son válidas. No se trata de una guerra de religiones, sino de usar lo que más encaje en cada capa.

AspectoVarnish CacheNginx (reverse proxy + proxy_cache)
Enfoque principalAcelerador HTTP puro, diseñado para cachéServidor web + proxy inverso con caché integrada
Configuración de cachéLenguaje VCL muy flexibleDirectivas en bloques (location, proxy_cache_*)
Soporte de TLSTradicionalmente delante (Nginx/HAProxy) o módulosIntegrado, muy maduro
Integración con WordPressVía headers, cookies y VCL a medidaVía headers, cookies y map/if/location
Curva de aprendizajeAlgo más técnica (VCL)Más familiar para quien ya usa Nginx
Uso típico en CDNs propiasCapa principal de caché/edgeTLS + caché simple, o solución todo-en-uno en PoPs

En muchos despliegues se combinan: Nginx para TLS y como backend de Varnish; en otros, Nginx hace de proxy caché directamente en los PoPs y Varnish se reserva para el origen. Depende de tu experiencia y de cuánta lógica quieras meter en el edge.


5 pasos para montar una CDN propia para WordPress

1. Definir objetivos y casos de uso (no solo “quiero una CDN”)

Antes de tocar servidores, compensa responder a:

  • ¿Qué tipo de WordPress es? ¿Blog, medio, tienda, SaaS, intranet?
  • ¿Dónde están los usuarios? ¿Un país, un continente, global?
  • ¿Qué duele más ahora mismo?
    • ¿Latencia para usuarios lejanos?
    • ¿Carga en PHP/DB?
    • ¿Factura de CDN comercial?
  • ¿Qué no se puede cachear bajo ningún concepto?
    (backoffice, login, carrito, cuentas, ciertas APIs).

Esto marcará:

  • Cuántos PoPs tiene sentido desplegar.
  • Qué tipo de contenido se va a cachear en el edge (solo estáticos vs HTML completo).
  • Hasta dónde quieres seguir usando una CDN de terceros como refuerzo.

2. Elegir dónde vivirán origen y PoPs (cloud, on-prem o híbrido)

Para un administrador de sistemas, la primera decisión real es de infraestructura:

  • ¿Origen WordPress?
    • ¿En tu propio CPD / bare-metal?
    • ¿En cloud (AWS, GCP, OVH, etc.)?
  • ¿PoPs?
    • ¿Instancias ligeras en varias regiones cloud?
    • ¿Servidores físicos en operadores que ya usas?
    • ¿Mezcla de ambos?

Criterios prácticos:

  • Latencia hacia tus usuarios principales.
  • Capacidad para soportar picos (CPU, RAM, ancho de banda).
  • Precio por TB transferido y coste total frente a seguir solo con CDN comercial.
  • Operación: ¿qué te resulta más sencillo monitorizar, automatizar y actualizar?

No hace falta empezar con 10 PoPs. A menudo, 2–3 bien situados aportan más que un despliegue excesivo que luego no se mantiene.


3. Levantar el origin shield con caché “inteligente”

El origin shield es el punto donde tiene sentido invertir más tiempo en lógica:

  • Delante de tus servidores WordPress.
  • Recibe todas las peticiones que no están ya servidas por un PoP.
  • Decide qué se cachea, cuánto tiempo y con qué condiciones.

Ejemplo simplificado con Varnish:

vcl 4.1;

backend wp_backend {
    .host = "10.0.0.10";
    .port = "8080";
}

sub vcl_recv {
    # No cachear admin ni login
    if (req.url ~ "^/wp-admin/" ||
        req.url ~ "^/wp-login\.php") {
        return (pass);
    }

    # No cachear usuarios autenticados ni carritos
    if (req.http.Cookie ~ "wordpress_logged_in_" ||
        req.http.Cookie ~ "woocommerce_cart_hash" ||
        req.http.Cookie ~ "woocommerce_items_in_cart") {
        return (pass);
    }

    # Solo cachear GET/HEAD
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    return (hash);
}

sub vcl_backend_response {
    # TTL por defecto para HTML
    set beresp.ttl = 120s;

    # Más TTL para estáticos
    if (bereq.url ~ "\.(css|js|jpe?g|png|webp|svg|woff2?)$") {
        set beresp.ttl = 1h;
    }

    # Grace para servir contenido aunque el backend esté lento
    set beresp.grace = 5m;
}
Lenguaje del código: PHP (php)

El equivalente con Nginx usaría proxy_cache, proxy_cache_key, proxy_cache_valid, etc., y la lógica de cookies se puede tratar con map y if en los bloques location.

Lo importante es:

  • No cachear nada que dependa de sesión/usuario correcto.
  • Dar TTLs generosos a assets estáticos.
  • Permitir un poco de “grace” para absorber picos.

4. Desplegar PoPs con Varnish o Nginx y enrutar el tráfico

Cada PoP actúa como un mini reverse proxy cerca del usuario:

  • Recibe tráfico para cdn.midominio.com, static.midominio.com o incluso el dominio principal si te atreves a cachear HTML agresivamente.
  • Sirve contenido desde su propia caché local.
  • Si no tiene el objeto, lo pide al origin shield.

Con Nginx, por ejemplo:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:500m max_size=50g inactive=60m use_temp_path=off;

server {
    listen 80;
    server_name static.midominio.com;

    location / {
        proxy_pass http://origin-shield;

        proxy_cache WORDPRESS;
        proxy_cache_valid 200 301 302 1h;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        add_header X-Cache-Status $upstream_cache_status;
    }
}
Lenguaje del código: PHP (php)

A nivel de DNS / routing:

  • Puedes usar GeoDNS para resolver static.midominio.com a la IP del PoP más cercano.
  • O un anycast BGP si tienes esa capacidad, anunciando la misma IP desde varios PoPs.
  • O incluso un balanceador global que haga health checks y routing por región.

La filosofía es simple: cuanto más cerca esté la caché del usuario, menos latencia y menos carga en origen.


5. Integrar WordPress: purgas finas y coherencia de contenido

Montar cachés sin pensar en el flujo editorial es la receta perfecta para que la CDN acabe desactivada “porque no vemos los cambios”.

La clave está en cómo y cuándo se purga:

  • Cuando se publica o actualiza un post.
  • Cuando cambia la portada, menús, widgets, etc.
  • Cuando se borra contenido.

Opciones:

  • Plugins que soporten purga hacia Varnish o Nginx (por URL o por patrón).
  • Un pequeño plugin propio que llame a una API interna de purga cada vez que salta un hook (save_post, transition_post_status, etc.).

Ejemplo de purga simple por URL:

curl -X PURGE "https://cdn.midominio.com/ruta/de/la/entrada/"
Lenguaje del código: JavaScript (javascript)

O, en Nginx, usando un método especial que invalide el objeto en proxy_cache si se configura así.

Combinando:

  • TTLs cortos para HTML (1–5 minutos).
  • TTLs largos para estáticos.
  • Purgas selectivas cuando hay cambios importantes.

…se consigue un equilibrio razonable entre frescura y rendimiento sin que los editores o el equipo de contenido noten “retardos misteriosos”.


¿Y qué pasa con la CDN comercial?

Montar una CDN propia no obliga a renunciar a todo lo anterior. Muchos equipos optan por:

  • Mantener una CDN comercial para ciertas regiones o como “cinturón de seguridad”.
  • Usarla solo para DDoS, WAF y TLS gestionado si eso les simplifica la vida.
  • O dejarla como capa opcional para algunos dominios o proyectos concretos.

La ventaja de tener tu propia red de PoPs es que la decisión deja de ser binaria:

  • Puedes derivar parte del tráfico a tu infraestructura cuando te resulte más eficiente.
  • Puedes experimentar con políticas de caché que en la CDN comercial no serían posibles.
  • Puedes negociar con los proveedores desde una posición mucho más cómoda.

Conclusión: una CDN que habla el mismo idioma que tus servidores

Para un administrador de sistemas, una CDN propia basada en Varnish o Nginx es, sobre todo, coherencia técnica:

  • Misma filosofía de logs, monitorización y automatización que el resto de la plataforma.
  • Misma capacidad de depurar problemas con curl, tcpdump, journalctl o lo que ya usas cada día.
  • Misma cultura de infra-as-code para desplegar PoPs que para cualquier otro servicio.

No es una solución mágica ni gratuita en términos de tiempo, pero cuando WordPress deja de ser “una web” para convertirse en un pilar del negocio, tener el edge bajo tu control se vuelve una ventaja competitiva muy real.


Preguntas frecuentes

1. ¿Tiene sentido montar una CDN propia si ya uso Cloudflare o similar?
Sí, especialmente si gestionas varios WordPress con mucho tráfico o requisitos específicos (compliance, residencia de datos, reglas complejas de caché). Puedes mantener Cloudflare para DNS, WAF o ciertas regiones y usar tu CDN propia como primera capa de caché y control.

2. ¿Qué es más recomendable para empezar, Varnish o Nginx?
Depende de tu stack y equipo. Si ya dominas Nginx y quieres algo sencillo, proxy_cache puede ser un buen punto de partida. Si necesitas reglas de caché muy potentes y más flexibilidad, Varnish Cache encaja mejor como motor principal, dejando Nginx para TLS y backend.

3. ¿Es obligatorio cachear el HTML de WordPress en la CDN?
No. Puedes empezar cacheando solo contenidos estáticos (CSS, JS, imágenes) y, cuando tengas confianza en las reglas de purga e invalidación, extender la caché al HTML. Cada paso que acerques al edge reduce carga en el backend y mejora tiempos de respuesta.

4. ¿Qué herramientas recomiendan para monitorizar una CDN propia?
Lo habitual en entornos de sysadmin:

  • Métricas de Varnish (varnishstat) o Nginx (stub_status, vts, etc.) enviadas a Prometheus.
  • Dashboards en Grafana para ver hit ratio, latencias, errores 5xx y uso de caché.
  • Logs centralizados (Elastic, Loki, etc.) para correlacionar problemas entre PoPs, origin shield y servidores WordPress.

Editor WPDirecto

Editor de WPDirecto potenciado con IA con el apoyo del equipo de edición.

Te puede interesar...

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    WordPress Directo
    WPDirecto.com es una revista especializada en WordPress y WooCommerce que ofrece una amplia gama de recursos, incluyendo tutoriales, análisis de plugins y plantillas, consejos de optimización y estrategias de SEO, para ayudar a los usuarios a mejorar y personalizar sus sitios web, manteniéndolos informados sobre las últimas novedades y tendencias en el mundo de WordPress.

    © 1995-2025 Color Vivo Internet, SLU (Medios y Redes Online).. Otros contenidos se cita fuente. Infraestructura cloud servidores dedicados de Stackscale.