Ворклог по задаче "Настроить кеширование varnish"
Настроено кеширование статических ресурсов через Varnish
Для сайта gorodskie-bani.ru настроено проксирование статических ресурсов через Varnish с TTL 7 дней. Через кеш проходят JS, CSS, шрифты, изображения, иконки и ресурсы /styles/ от tileserver. Динамические страницы намеренно не кешируются и продолжают обрабатываться приложением напрямую (return (pass)).
Зачем это нужно
Основная задача кеширования — отдавать неизменяемые и редко меняющиеся ресурсы не из Node.js-приложения и tileserver при каждом запросе, а непосредственно из памяти/кеша Varnish.
Это даёт сайту несколько практических преимуществ:
- Снижается время отдачи статики. После первого запроса ресурс попадает в кеш, последующие запросы обслуживаются Varnish без обращения к backend.
- Уменьшается нагрузка на приложение и tileserver. JS, CSS, изображения, шрифты и стили карты не создают повторную нагрузку на backend-контейнеры.
- Повышается стабильность под нагрузкой. При одновременных заходах пользователей большая часть запросов к статике обслуживается на уровне кеширующего прокси.
- Ускоряется загрузка страниц для пользователей. Быстрая отдача CSS, JS, шрифтов и изображений уменьшает ожидание ресурсов, необходимых для отрисовки страницы.
- Создаётся положительный технический эффект для SEO. Скорость загрузки и пользовательские метрики производительности, в том числе связанные с Core Web Vitals, являются частью технического качества сайта. Varnish не меняет позиции в поиске напрямую, но помогает уменьшить сетевые задержки и нагрузку на origin, что создаёт более стабильные условия для быстрой загрузки и обхода сайта поисковыми роботами.
Конфигурация Varnish
Настроены два backend:
- основной backend приложения —
gorodskie-bani--agent-app-1:3000; - отдельный backend tileserver —
gorodskie-bani-ru-tileserver-1:80.
vcl 4.1;
backend default {
.host = "gorodskie-bani--agent-app-1";
.port = "3000";
}
backend tileserver {
.host = "gorodskie-bani-ru-tileserver-1";
.port = "80";
}
В vcl_recv запросы к /styles/ отправляются в tileserver. Для кешируемых ресурсов Cookie удаляются, чтобы пользовательские cookies не дробили кеш и не мешали повторному использованию одного объекта разными запросами.
sub vcl_recv {
if (req.url ~ "^/styles/") {
set req.backend_hint = tileserver;
unset req.http.Cookie;
return (hash);
}
if (req.url ~ "\.(js|css|woff2?|ttf|eot|svg|ico|png|jpg|jpeg|gif|webp|avif)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
return (pass);
}
Все остальные запросы идут через pass, то есть HTML и динамические ответы приложения этим правилом не кешируются. Это снижает риск отдачи устаревшего персонализированного или динамического контента.
Ключ кеша строится по URL и host:
sub vcl_hash {
hash_data(req.url);
hash_data(req.http.host);
return (lookup);
}
Это позволяет раздельно хранить ресурсы разных URL и не смешивать кеш между хостами. Query string остаётся частью req.url, поэтому версии ассетов с cache-busting параметрами получают отдельные записи кеша.
Для /styles/ и статических файлов задан TTL 7 дней, а Set-Cookie удаляется из кешируемых backend-ответов:
sub vcl_backend_response {
if (bereq.url ~ "^/styles/") {
set beresp.ttl = 7d;
unset beresp.http.Set-Cookie;
}
if (bereq.url ~ "\.(js|css|woff2?|ttf|eot|svg|ico|png|jpg|jpeg|gif|webp|avif)(\?.*)?$") {
set beresp.ttl = 7d;
unset beresp.http.Set-Cookie;
}
}
TTL 7 дней позволяет долго обслуживать повторные запросы из Varnish, при этом стандартный подход с версионированными именами файлов или query-параметрами позволяет получать новую версию ресурса после деплоя без ожидания истечения старого кеша.
Для диагностики добавлены служебные заголовки X-Cache и X-Cache-TTL:
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Cache-TTL = obj.ttl;
}
По ним можно быстро проверить фактическую работу кеша: первый запрос обычно отдаётся как MISS, последующие — как HIT, а X-Cache-TTL показывает оставшееся время жизни объекта.
Маршрутизация Traefik
Чтобы нужные запросы действительно попадали в Varnish, в Traefik добавлены отдельные роутеры с высоким приоритетом.
Статические файлы:
gorodskie-bani.ru-static:
rule: 'Host(`gorodskie-bani.ru`) && PathRegexp(`^.*\.(js|css|woff2?|ttf|eot|svg|ico|png|jpg|jpeg|gif|webp|avif)$`)'
entryPoints:
- websec
service: gorodskie-bani.ru-varnish
tls:
certResolver: letsencrypt
priority: 200
Ресурсы /styles:
gorodskie-bani.ru-styles:
rule: "Host(`gorodskie-bani.ru`) && PathPrefix(`/styles`)"
entryPoints:
- websec
middlewares: []
service: gorodskie-bani.ru-varnish
tls:
certResolver: letsencrypt
priority: 200
Таким образом, Traefik отделяет кешируемые запросы на входе и передаёт их в сервис Varnish, после чего Varnish либо отдаёт объект из кеша, либо получает его с соответствующего backend и сохраняет на 7 дней.
Итог для сайта и SEO
В результате статическая часть gorodskie-bani.ru обслуживается через отдельный кеширующий слой. Это уменьшает количество обращений к приложению и tileserver, ускоряет повторную загрузку ресурсов и делает время ответа более стабильным при росте трафика.
Для SEO это полезно прежде всего как инфраструктурная оптимизация производительности: браузер быстрее получает критические CSS/JS/шрифты/изображения, backend меньше конкурирует за ресурсы со статическими запросами, а сайт устойчивее сохраняет нормальную скорость ответа под нагрузкой. В совокупности это помогает техническому качеству сайта и пользовательскому опыту, которые важны для поисковой видимости и эффективности органического трафика.