--- title: "Cómo instalar y configurar Varnish Cache en Ubuntu 24.04" description: "Instala Varnish Cache delante de Nginx en Ubuntu 24.04, escribe una VCL con TTL, cookies y purga, y comprueba con curl y varnishstat que la caché funciona." category: "Servidores Web" language: es source: https://cubepath.com/es/docs/servidores-web/configuracion-de-cache-varnish updated: 2026-09-25 --- # Cómo instalar y configurar Varnish Cache en Ubuntu 24.04 Varnish Cache es un proxy inverso HTTP que guarda en memoria las respuestas de tu servidor web y las sirve directamente en las siguientes peticiones, sin volver a ejecutar PHP, consultas a la base de datos ni el resto de la aplicación. En este tutorial pondrás Varnish en el puerto 80 de un servidor Ubuntu 24.04, delante de Nginx, que pasará a escuchar solo en local en el puerto 8080. Escribirás una configuración VCL con reglas de TTL, cookies, purga y chequeos de salud, y comprobarás los aciertos de caché con `curl`, `varnishstat` y `varnishlog`. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 1 GB de RAM. Varnish guarda la caché en memoria, así que cuanta más RAM le dediques, más objetos podrá almacenar. - Un usuario no root con privilegios `sudo`. - Nginx instalado y sirviendo tu sitio en el puerto 80. Si aún no lo tienes, instálalo con `sudo apt install nginx`. - UFW activo con SSH permitido, si usas firewall. > Nota: Varnish no gestiona HTTPS. Esta guía cubre el tráfico HTTP en el puerto 80. Para servir HTTPS, lo habitual es terminar TLS en Nginx (puerto 443) y reenviar a Varnish, que a su vez consulta al backend. ## Paso 1: Instalar Varnish Ubuntu 24.04 incluye Varnish 7.1 en sus repositorios, una versión estable y suficiente para todo lo que verás aquí. Instálalo: ```bash sudo apt update sudo apt install varnish ``` Comprueba la versión instalada: ```bash varnishd -V ``` ```output varnishd (varnish-7.1.1 revision ...) Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2022 Varnish Software ``` Tras la instalación Varnish ya está en marcha, escuchando en el puerto 6081 para el tráfico HTTP y en `localhost:6082` para la interfaz de administración. Los archivos que vas a tocar son: - `/etc/varnish/default.vcl`: la configuración VCL, que define el backend y las reglas de caché. - La unidad systemd `varnish.service`: los parámetros de arranque (puerto de escucha y tamaño de la caché). ## Paso 2: Mover Nginx al puerto 8080 Varnish tiene que recibir las peticiones en el puerto 80, así que antes hay que liberar ese puerto. Nginx pasará a escuchar en `127.0.0.1:8080`, de modo que solo Varnish podrá acceder a él. Abre el sitio por defecto de Nginx (o el archivo de tu sitio en `/etc/nginx/sites-available/`): ```bash sudo nano /etc/nginx/sites-available/default ``` Busca las líneas `listen` del bloque `server`: ```nginx listen 80 default_server; listen [::]:80 default_server; ``` Y sustitúyelas por: ```nginx listen 127.0.0.1:8080 default_server; ``` Repite el cambio en cada archivo de sitio habilitado que escuche en el puerto 80. Después comprueba la sintaxis y reinicia Nginx: ```bash sudo nginx -t sudo systemctl restart nginx ``` Verifica que Nginx responde en el nuevo puerto: ```bash curl -I http://127.0.0.1:8080 ``` ```output HTTP/1.1 200 OK Server: nginx/1.24.0 (Ubuntu) Content-Type: text/html ``` A partir de aquí, y hasta que termines el paso 4, el sitio no responderá en el puerto 80. ## Paso 3: Escribir la configuración VCL VCL (Varnish Configuration Language) define a qué backend se reenvían las peticiones y qué se guarda en caché. Varnish incluye una VCL integrada (`builtin.vcl`) que se ejecuta después de tus subrutinas si estas no terminan con `return`. Esa lógica ya hace lo correcto por defecto: no cachea peticiones `POST`, ni peticiones con cabecera `Authorization` o `Cookie`, ni respuestas con `Set-Cookie`. Por eso la mejor VCL suele ser corta y retocar solo lo necesario. Abre el archivo: ```bash sudo nano /etc/varnish/default.vcl ``` Sustituye su contenido por lo siguiente: ```vcl vcl 4.1; backend default { .host = "127.0.0.1"; .port = "8080"; .connect_timeout = 5s; .first_byte_timeout = 60s; .between_bytes_timeout = 10s; .probe = { .url = "/"; .timeout = 2s; .interval = 5s; .window = 5; .threshold = 3; } } acl purge { "localhost"; "127.0.0.1"; "::1"; } sub vcl_recv { # Permitir purgar una URL solo desde el propio servidor if (req.method == "PURGE") { if (!client.ip ~ purge) { return (synth(405, "Not allowed")); } return (purge); } # Nunca cachear zonas privadas if (req.url ~ "^/(admin|wp-admin|wp-login\.php|login|cart|checkout)") { return (pass); } # Los estáticos no necesitan cookies if (req.url ~ "\.(css|js|png|jpe?g|gif|svg|ico|webp|woff2?)(\?.*)?$") { unset req.http.Cookie; } # Quitar cookies de analítica, que no cambian el contenido if (req.http.Cookie) { set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_ga[^=]*|_gid|_gat|_fbp)=[^;]*", ""); set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", ""); if (req.http.Cookie ~ "^\s*$") { unset req.http.Cookie; } } # Sin return: se ejecuta la lógica de builtin.vcl } sub vcl_backend_response { # Los estáticos se guardan un día y sin cookies if (bereq.url ~ "\.(css|js|png|jpe?g|gif|svg|ico|webp|woff2?)(\?.*)?$") { unset beresp.http.Set-Cookie; set beresp.ttl = 1d; } # Si el backend cae, servir contenido caducado hasta 6 horas set beresp.grace = 6h; } sub vcl_deliver { # Cabecera para comprobar si la respuesta vino de la caché if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } ``` Qué hace cada bloque: - `backend default` apunta a Nginx en `127.0.0.1:8080`. La `probe` pide `/` cada 5 segundos y marca el backend como sano si al menos 3 de las últimas 5 respuestas son correctas. Si tu sitio tiene una URL de salud más ligera, úsala en `.url`. - `acl purge` y el bloque `PURGE` permiten invalidar una URL, pero solo desde el propio servidor. - `vcl_recv` excluye las zonas privadas de la caché y limpia cookies que impedirían cachear. Como no termina con `return`, después se aplica `builtin.vcl`, que sigue sin cachear peticiones con cookies de sesión. - `vcl_backend_response` asigna un TTL de un día a los estáticos. Para el resto, Varnish respeta las cabeceras `Cache-Control` y `Expires` del backend y, si no hay, usa un TTL por defecto de 120 segundos. - `beresp.grace` permite servir contenido caducado mientras se obtiene una copia nueva, o mientras el backend no responde. Comprueba que la VCL compila antes de cargarla. Si hay un error, `varnishd` indica la línea exacta: ```bash sudo varnishd -C -f /etc/varnish/default.vcl > /dev/null && echo "VCL OK" ``` ```output VCL OK ``` ## Paso 4: Poner Varnish en el puerto 80 El puerto de escucha y el tamaño de la caché se pasan como argumentos a `varnishd` en la unidad systemd. En Ubuntu 24.04 el archivo `/etc/default/varnish` no se usa, así que el cambio se hace con un override de systemd. Primero mira la línea `ExecStart` actual: ```bash systemctl cat varnish | grep -A3 ExecStart ``` ```output ExecStart=/usr/sbin/varnishd \ -j unix,user=vcache \ -F \ -a :6081 \ ``` Crea un override con el editor de systemd: ```bash sudo systemctl edit varnish ``` Escribe lo siguiente entre los comentarios que indica el editor. La primera línea `ExecStart=` vacía borra la original; la segunda es la nueva. Copia los argumentos que te mostró el comando anterior y cambia solo `-a` (puerto) y `-s` (tamaño de la caché): ```ini [Service] ExecStart= ExecStart=/usr/sbin/varnishd \ -j unix,user=vcache \ -F \ -a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,512m ``` `-s malloc,512m` reserva 512 MB de RAM para la caché. Ajústalo a tu servidor dejando memoria libre para Nginx, la aplicación y el sistema; Varnish usa algo más de memoria que la indicada por la gestión interna de cada objeto. Guarda el archivo y reinicia Varnish: ```bash sudo systemctl restart varnish ``` Comprueba que `varnishd` escucha en el puerto 80 y Nginx en el 8080: ```bash sudo ss -tlnp | grep -E ':(80|8080)\s' ``` ```output LISTEN 0 1024 0.0.0.0:80 0.0.0.0:* users:(("varnishd",pid=4321,fd=3)) LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("nginx",pid=1234,fd=5)) LISTEN 0 1024 [::]:80 [::]:* users:(("varnishd",pid=4321,fd=4)) ``` Si usas UFW, permite el tráfico HTTP. No abras el 8080: Nginx ya solo escucha en local. ```bash sudo ufw allow 80/tcp ``` ## Paso 5: Comprobar que la caché funciona Haz dos peticiones seguidas a la página principal y fíjate en la cabecera `X-Cache`: ```bash curl -sI http://localhost/ | grep -iE '^(x-cache|age)' curl -sI http://localhost/ | grep -iE '^(x-cache|age)' ``` ```output X-Cache: MISS Age: 0 X-Cache: HIT Age: 3 ``` La primera petición va al backend (`MISS`) y la segunda se sirve desde memoria (`HIT`). La cabecera `Age` indica cuántos segundos lleva el objeto en caché. Comprueba también que Varnish ve el backend como sano: ```bash sudo varnishadm backend.list ``` ```output Backend name Admin Probe Health Last change boot.default probe 5/5 healthy Thu, 25 Sep 2026 10:20:11 GMT ``` ## Paso 6: Purgar contenido de la caché Cuando publicas un cambio, no hace falta esperar a que caduque el TTL. Con la regla `PURGE` del paso 3 puedes invalidar una URL concreta desde el propio servidor: ```bash curl -X PURGE http://localhost/ ``` ```output 200 Purged ``` La siguiente petición a `/` volverá a ser un `MISS`. Para invalidar muchas URLs a la vez según un patrón, usa un ban desde `varnishadm`. Este ejemplo invalida todo lo que empiece por `/blog/`: ```bash sudo varnishadm "ban req.url ~ ^/blog/" ``` Y para vaciar la caché por completo: ```bash sudo varnishadm "ban req.url ~ ." ``` Otra opción es reiniciar Varnish, que también vacía la caché porque vive en memoria. ## Paso 7: Monitorizar la caché `varnishstat` muestra los contadores internos. Para ver de un vistazo los aciertos, fallos y objetos almacenados: ```bash varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss -f MAIN.n_object ``` ```output MAIN.cache_hit 1520 0.52 Cache hits MAIN.cache_miss 312 0.11 Cache misses MAIN.n_object 287 . object structs made ``` La tasa de aciertos es `cache_hit / (cache_hit + cache_miss)`, en este ejemplo un 83 %. Sin argumentos, `varnishstat` abre una vista interactiva que se actualiza en tiempo real. `varnishlog` muestra cada petición en detalle. Es la herramienta para averiguar por qué algo no se cachea. Por ejemplo, para seguir las peticiones a la portada agrupadas por petición: ```bash sudo varnishlog -g request -q 'ReqURL eq "/"' ``` En la salida, las líneas `VCL_call` y `VCL_return` indican por qué subrutinas pasó la petición (`HIT`, `MISS` o `PASS`), y las cabeceras `ReqHeader` y `BerespHeader` muestran si había cookies o un `Cache-Control` que impidió cachear. ## Solución de problemas **Todas las respuestas son `MISS`**: lo más habitual es que el navegador o la aplicación envíen cookies de sesión, o que el backend responda con `Set-Cookie` o `Cache-Control: private` o `no-cache`. Revisa las cabeceras con `sudo varnishlog -g request -q 'ReqURL eq "/"'`. Si la aplicación usa cookies de sesión en todas las páginas, tendrás que decidir qué cookies ignorar en `vcl_recv`. **Error `503 Backend fetch failed`**: Varnish no puede hablar con Nginx. Comprueba que Nginx responde con `curl -I http://127.0.0.1:8080`, que `varnishadm backend.list` muestra el backend como `healthy` y revisa los logs con `sudo journalctl -u varnish -n 50`. Si la `probe` falla porque `/` devuelve un error o una redirección, cambia `.url` por una ruta que devuelva `200`. **Varnish no arranca tras el override**: normalmente es un error en la VCL o un argumento mal copiado. Ejecuta `sudo journalctl -u varnish -n 30` y valida la VCL con `sudo varnishd -C -f /etc/varnish/default.vcl`. **Los logs de Nginx muestran siempre `127.0.0.1` como cliente**: es normal, porque ahora todas las peticiones llegan desde Varnish. Varnish añade la IP real en la cabecera `X-Forwarded-For`; configura el módulo `real_ip` de Nginx con `set_real_ip_from 127.0.0.1;` y `real_ip_header X-Forwarded-For;` para recuperarla. ## Conclusión Has instalado Varnish Cache en Ubuntu 24.04 delante de Nginx, has escrito una VCL que cachea los estáticos, respeta las zonas privadas, sirve contenido caducado si el backend cae y permite purgas locales, y has comprobado los aciertos con `curl`, `varnishstat` y `varnishlog`. Como siguientes pasos puedes: - Terminar HTTPS en Nginx en el puerto 443 y reenviar el tráfico a Varnish. - Ajustar las reglas de cookies y TTL a tu aplicación (por ejemplo WordPress o una API) observando `varnishlog`. - Enviar `varnishncsa` a tus logs de acceso para tener registros en formato Apache de las peticiones servidas por Varnish.