Varnish Cache — konfiguracja i integracja z WordPress
Czym jest Varnish Cache i kiedy go używać?
Varnish Cache to reverse proxy HTTP umieszczony przed serwerem webowym (Apache/Nginx). Przechowuje odpowiedzi w pamięci RAM i serwuje je bezpośrednio dla kolejnych żądań — bez przetwarzania przez PHP/MySQL. Typowy efekt: 10-100x większa przepustowość dla stron z dużym ruchem.
| Sytuacja | Varnish pomaga? | Uwagi |
|---|---|---|
| Blog/strona z dużym ruchem | Tak — bardzo | Cache ratio 90%+ dla anonimowych użytkowników |
| Sklep WooCommerce | Częściowo | Strony produktów tak, koszyk/checkout — nie |
| Aplikacja z logowaniem | Ograniczone | Zalogowani użytkownicy — trudna konfiguracja |
| API REST | Tak (GET) | Cache dla GET, pomijaj POST/PUT/DELETE |
Powiązane tematy: Redis cache WordPress, WordPress cache optymalizacja, konfiguracja Nginx. Porównaj serwery VPS na stronie VPS.
Instalacja Varnish Cache
# Ubuntu 22.04/24.04 — oficjalne repo Varnish
sudo apt update
sudo apt install apt-transport-https
# Dodaj klucz i repo Varnish 7.x
curl -s https://packagecloud.io/varnishcache/varnish76/gpgkey | sudo apt-key add -
. /etc/os-release
sudo sh -c "echo 'deb https://packagecloud.io/varnishcache/varnish76/ubuntu/ $VERSION_CODENAME main' > /etc/apt/sources.list.d/varnishcache_varnish76.list"
sudo apt update
sudo apt install varnish
# Sprawdź wersję
varnishd -V Zmiana portów
Domyślnie Varnish nasłuchuje na porcie 6081. Zmień tak, żeby Varnish był na porcie 80, a Apache/Nginx na 8080 (lub innym wewnętrznym).
# /etc/default/varnish
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"
# Lub przez systemd override (zalecane)
sudo systemctl edit varnish
# Dodaj:
# [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,256m Podstawowa konfiguracja VCL
VCL (Varnish Configuration Language) to język konfiguracji Varnish — deklaratywny,
zbliżony do C. Najważniejsze funkcje to vcl_recv (obsługa żądania) i vcl_backend_response (obsługa odpowiedzi z backendu).
# /etc/varnish/default.vcl
vcl 4.1;
backend default {
.host = "127.0.0.1";
.port = "8080"; # Port Apache/Nginx
}
sub vcl_recv {
# Usuń port z nagłówka Host
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Nie cache'uj żądań z metodą POST/PUT/DELETE/PATCH
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Nie cache'uj zalogowanych użytkowników (WordPress cookies)
if (req.http.Cookie ~ "wordpress_logged_in|woocommerce_cart") {
return (pass);
}
# Usuń zbędne cookies od przeglądarki (analytics, itp.)
unset req.http.Cookie;
return (hash);
}
sub vcl_backend_response {
# Cache przez 1 godzinę (override Cache-Control backendu)
set beresp.ttl = 1h;
set beresp.grace = 15m;
# Nie cache'uj błędów serwera
if (beresp.status >= 500) {
set beresp.uncacheable = true;
set beresp.ttl = 0s;
}
} Integracja z WordPress
WordPress używa cookies do śledzenia sesji i koszyka. Varnish musi omijać cache dla zalogowanych użytkowników i specjalnych stron.
sub vcl_recv {
# Przepuść zalogowanych i koszyk bez cache
if (req.http.Cookie ~ "wordpress_logged_in|wp-postpass|woocommerce_cart_hash|woocommerce_items_in_cart") {
return (pass);
}
# Nie cache'uj stron admina, logowania, checkoutu
if (req.url ~ "^/wp-(admin|login|cron)") {
return (pass);
}
if (req.url ~ "^/(cart|checkout|my-account)") {
return (pass);
}
# Usuń cookies analityczne (nie blokuj cache)
if (req.http.Cookie) {
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_ga|_gid|_gat|_fbp|_fbc)[^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
} Wtyczki WordPress do Varnish
Użyj wtyczki Proxy Cache Purge (dawniej Varnish HTTP Purge) — wysyła PURGE request do Varnish po opublikowaniu/aktualizacji posta.
Purging cache — ręczne i automatyczne
# Ręczne purge konkretnej strony
curl -X PURGE http://localhost/strona/
# Purge całego cache (BAN method — Varnish Plus lub custom)
# W VCL dodaj endpoint PURGE:
sub vcl_recv {
if (req.method == "PURGE") {
if (req.http.X-Purge-Token != "twoj-tajny-token") {
return (synth(403, "Forbidden"));
}
return (purge);
}
}
# Wyczyść cały cache przez varnishadm
sudo varnishadm "ban req.url ~ /" Monitorowanie Varnish
# Statystyki na żywo (hit ratio, żądania/s, itp.)
varnishstat
# Top 10 najczęściej odwiedzanych URL
varnishtop -i ReqURL
# Log requestów
varnishlog
# Hit ratio — kluczowa metryka
# MISS = żądanie do backendu, HIT = z cache
# Cel: HIT ratio >= 80%
varnishstat -1 | grep "MAIN.cache_hit\|MAIN.cache_miss"
# Oblicz hit ratio
HITS=$(varnishstat -1 -f MAIN.cache_hit | awk '{print $2}')
MISSES=$(varnishstat -1 -f MAIN.cache_miss | awk '{print $2}')
echo "Hit ratio: $(echo "scale=2; $HITS * 100 / ($HITS + $MISSES)" | bc)%" Typowe problemy i rozwiązania
| Problem | Przyczyna | Rozwiązanie |
|---|---|---|
| Hit ratio = 0% | Każde żądanie trafia do backendu | Sprawdź czy cookies nie blokują cache (varnishlog -g request) |
| Strony z logowaniem tracą sesję | Varnish stripuje cookies | Dodaj wyjątek dla ciasteczek sesji przed unset req.http.Cookie |
| Cache nie odświeża po update | Brak PURGE po publikacji | Zainstaluj wtyczkę Proxy Cache Purge lub skonfiguruj BAN |
| 503 Backend Fetch Failed | Backend niedostępny | Sprawdź czy Apache/Nginx działa na porcie 8080 |