Nginx FastCGI Cache — konfiguracja, bypass i WordPress
Opublikowano: 10 kwietnia 2026 · Kategoria: Wydajność
WordPress generuje każdą stronę od nowa: zapytanie do bazy, parsowanie PHP, budowanie HTML. Nawet zoptymalizowany WordPress potrzebuje 200-500 ms na odpowiedź. Nginx FastCGI Cache zapisuje gotowe odpowiedzi HTTP na dysku i serwuje je bez uruchamiania PHP-FPM — czas odpowiedzi spada do 1-5 ms. To najszybszy możliwy cache dla stron PHP bez dodatkowego oprogramowania.
Podstawowa konfiguracja fastcgi_cache_path
Konfiguracja FastCGI Cache zaczyna się w bloku http {} pliku
/etc/nginx/nginx.conf lub osobnym pliku conf.d/fastcgi-cache.conf.
Dyrektywa fastcgi_cache_path definiuje lokalizację na dysku, hierarchię katalogów
i rozmiar pamięci dla kluczy cache:
# /etc/nginx/conf.d/fastcgi-cache.conf lub w bloku http {} nginx.conf
fastcgi_cache_path /var/cache/nginx/wordpress
levels=1:2
keys_zone=wordpress_cache:100m
max_size=2g
inactive=60m
use_temp_path=off;
# Wyjaśnienie parametrów:
# /var/cache/nginx/wordpress — katalog na dysku (musi istnieć, właściciel nginx)
# levels=1:2 — hierarchia podkatalogów (performance przy dużej liczbie plików)
# keys_zone=wordpress_cache — nazwa strefy + 100m RAM na klucze (ok. 800 tys. kluczy)
# max_size=2g — maksymalny rozmiar cache na dysku
# inactive=60m — usuń plik cache jeśli nie był żądany przez 60 minut
# use_temp_path=off — zapisuj bezpośrednio do docelowego katalogu (szybciej na NVMe)
# Utwórz katalog i nadaj uprawnienia
sudo mkdir -p /var/cache/nginx/wordpress
sudo chown nginx:nginx /var/cache/nginx/wordpress Konfiguracja virtual hosta z FastCGI Cache
W bloku server {} dla WordPress definiujemy klucz cache, czas ważności,
nagłówki diagnostyczne i reguły przekazywania do PHP-FPM. Kluczowa jest dyrektywa fastcgi_cache_key — na jej podstawie Nginx identyfikuje czy dana odpowiedź jest w cache:
# /etc/nginx/sites-available/wordpress.conf
# Zmienne bypass — ustawiamy poza blokiem server
map $http_cookie $skip_cache {
default 0;
"~*wordpress_logged_in" 1;
"~*comment_author" 1;
"~*woocommerce_cart_hash" 1;
"~*woocommerce_items_in_cart" 1;
}
server {
listen 443 ssl http2;
server_name mojadomena.pl www.mojadomena.pl;
root /var/www/wordpress;
index index.php;
# Klucz cache — unikalny identyfikator żądania
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# Nagłówek diagnostyczny — HIT/MISS/BYPASS/EXPIRED
add_header X-Cache $upstream_cache_status;
# Strefa cache (nazwa z fastcgi_cache_path)
fastcgi_cache wordpress_cache;
# Czas ważności odpowiedzi z kodem 200
fastcgi_cache_valid 200 301 302 60m;
# Serwuj stale dane gdy PHP-FPM nie odpowiada (optional)
fastcgi_cache_use_stale error timeout updating http_500 http_503;
fastcgi_cache_background_update on;
fastcgi_cache_lock on;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Włącz cache i bypass
fastcgi_cache wordpress_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $skip_cache $http_pragma;
fastcgi_no_cache $skip_cache;
# Pomijaj cache dla POST (formularze, AJAX)
fastcgi_cache_methods GET HEAD;
}
} Bypass dla zalogowanych użytkowników i WooCommerce
Zalogowani użytkownicy i strony koszyka WooCommerce muszą pomijać cache — inaczej użytkownik A widzi prywatne dane użytkownika B. Poniższy snippet rozszerza logikę bypass o URL-based rules i obsługę WooCommerce:
# W bloku server {} — przed blokami location
# Zmienna dla bypass oparty o URL
set $skip_cache 0;
# Panel admina i logowanie — zawsze bypass
if ($request_uri ~* "(/wp-admin/|/wp-login.php|/xmlrpc.php)") {
set $skip_cache 1;
}
# WooCommerce — koszyk, checkout, konto użytkownika
if ($request_uri ~* "(/cart/|/checkout/|/my-account/|\\?wc-ajax=)") {
set $skip_cache 1;
}
# Żądania POST — zawsze generuj świeżą odpowiedź
if ($request_method = POST) {
set $skip_cache 1;
}
# Query string — np. ?preview=true, ?nocache=1
if ($query_string != "") {
set $skip_cache 1;
} Integracja z WordPress — Nginx Cache Controller
Plugin Nginx Cache Controller (lub Nginx Helper)
automatycznie inwaliduje cache po opublikowaniu wpisu, edycji lub dodaniu komentarza. Plugin
wysyła żądanie PURGE do Nginx, który usuwa odpowiednie pliki z /var/cache/nginx/wordpress/. Aby PURGE działał, Nginx potrzebuje modułu ngx_cache_purge:
# Sprawdź czy ngx_cache_purge jest dostępny
nginx -V 2>&1 | grep cache_purge
# Na Ubuntu — zainstaluj nginx z modułem purge
sudo apt install nginx-extras
# Alternatywnie: ręczne czyszczenie cache przez skrypt
# /usr/local/bin/nginx-cache-clear.sh
#!/bin/bash
CACHE_DIR="/var/cache/nginx/wordpress"
find ${CACHE_DIR} -type f -delete
echo "FastCGI cache cleared: ${CACHE_DIR}"
# Konfiguracja Nginx dla PURGE (jeśli masz ngx_cache_purge)
# W bloku server {}:
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
fastcgi_cache_purge wordpress_cache "$scheme$request_method$host$1";
} Benchmarki FastCGI Cache vs Redis page cache
Porównanie wydajności na typowym serwerze VPS (2 vCPU, 4 GB RAM, NVMe SSD), WordPress z 50
wpisami, test Apache Bench: ab -n 1000 -c 50 https://mojadomena.pl/:
| Konfiguracja | Req/s | Śr. czas [ms] | P99 [ms] | Użycie RAM |
|---|---|---|---|---|
| Bez cache (PHP-FPM + MySQL) | 12 | 420 | 850 | ~180 MB |
| Redis Object Cache (WP plugin) | 45 | 110 | 230 | ~220 MB |
| Redis Full Page Cache | 180 | 18 | 45 | ~260 MB |
| Nginx FastCGI Cache (dysk) | 950 | 3 | 8 | ~160 MB |
| FastCGI Cache + Redis (hybrydowy) | 1100 | 2 | 6 | ~240 MB |
Nginx FastCGI Cache wygrywa pod względem przepustowości (950 req/s vs 180 dla Redis Full Page Cache) i zużywa mniej RAM — bo cache jest na dysku, nie w pamięci. Wąskie gardło to I/O dysku; na NVMe SSD różnica jest minimalna. Konfiguracja hybrydowa (FastCGI na dysku + Redis dla obiektów WordPress) daje najlepsze wyniki.
Diagnostyka i monitorowanie cache
# Sprawdź nagłówek X-Cache
curl -I https://mojadomena.pl/
# X-Cache: HIT — serwowane z cache
# X-Cache: MISS — pobrane z PHP, zapisano do cache
# X-Cache: BYPASS — pominięto cache (zalogowany użytkownik)
# Sprawdź rozmiar cache na dysku
du -sh /var/cache/nginx/wordpress/
ls -la /var/cache/nginx/wordpress/ | wc -l # liczba plików
# Czyść cache ręcznie
sudo find /var/cache/nginx/wordpress/ -type f -delete
# Sprawdź logi Nginx dla błędów cache
sudo tail -f /var/log/nginx/error.log | grep cache
# Statystyki przez nginx status module
# W konfiguracji:
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}