Przejdź do treści

Cloudflare i samodzielne hostowanie Next.js

Cloudflare jako bezpłatny CDN i ochrona DDoS dla samodzielnie hostowanego Next.js. Jak skonfigurować go bez przypadkowego cache'owania API?

Maciej Sala

Founder StriveLab

8 min czytaniaOpublikowano 11 kwietnia 2026 (Aktualizacja 8 lipca 2026)

Darmowy plan Cloudflare obejmuje DNS, proxy, globalną sieć serwerów brzegowych, podstawową ochronę DDoS, SSL/TLS i Cache Rules. Może nie zastąpi poprawnie skonfigurowanego serwera, ale jako front dla samodzielnie hostowanego Next.js sprawdza się bardzo dobrze.

Konfiguracja Cloudflare dla Next.js krok po kroku

1. DNS w Cloudflare i przeniesienie domeny

Zmień nameservery domeny na te podane w dashboardzie Cloudflare. Po propagacji, zwykle w ciągu 2-24 godzin, Cloudflare zacznie zarządzać DNS-em.

Dodaj rekordy:

Code
Typ   Nazwa           Wartość              Proxy
A     example.com     IP_TWOJEGO_VPS       Proxied (pomarańczowa chmurka)
CNAME www             example.com          Proxied

(pomarańczowa chmurka) oznacza, że ruch przechodzi przez Cloudflare i korzysta z CDN, ochrony DDoS oraz cache. DNS only (szara chmurka) tylko rozwiązuje DNS, bez proxy, cache i ochrony na serwerach brzegowych.

2. SSL Full (Strict) dla Next.js za Cloudflare

Ustawienia zmienisz w panelu Cloudflare, przechodząc kolejno przez zakładki wskazane strzałkami. Rozpocznij od Dashboard → SSL/TLS → Overview:

  1. Flexible. SSL działa między użytkownikiem a Cloudflare, ale do Twojego serwera ruch idzie po HTTP. Unikaj tego trybu przy logowaniu, płatnościach i danych użytkownika.
  2. Full. Ruch jest szyfrowany na całej trasie, ale Cloudflare zaakceptuje też certyfikat wystawiony samodzielnie na serwerze.
  3. . W tym wariancie, który jest najlepszy, ruch jest szyfrowany na całej trasie, a Cloudflare sprawdza certyfikat serwera źródłowego. Wymaga ważnego certyfikatu na serwerze, np. Let's Encrypt albo Cloudflare Origin CA.
Code
# Na VPS-ie zainstaluj certbot
sudo certbot --nginx -d example.com -d www.example.com

3. Cache Rules dla statycznych plików Next.js

Next.js generuje statyczne pliki w /_next/static/ z hashem zawartości w nazwie. Po zmianie pliku zmienia się też jego adres, więc Cloudflare może przechowywać takie zasoby w cache przez długi czas.

Dashboard → Caching → Cache Rules → Create Rule:

Code
Nazwa: Next.js Static Assets
If: URI Path starts with "/_next/static/"
Then: Cache eligible, Edge TTL = 1 year, Browser TTL = 1 year
Code
Nazwa: Next.js Images
If: URI Path starts with "/_next/image"
Then: Cache eligible, Edge TTL = 1 day, Browser TTL = 1 day

Przy /_next/image dobierz czas cache do źródła obrazów. Jeśli obrazy z CMS-a albo zewnętrznego CDN-u mogą zmieniać się pod tym samym adresem, zbyt długi cache w przeglądarce utrudni szybką podmianę. W takim przypadku lepiej wersjonować adresy obrazów albo ustawić krótszy czas cache.

Code
Nazwa: Versioned Static Files
If: URI Path matches regex "\.[a-f0-9]{8,}\.(js|css|woff2|svg|png|jpg|webp|avif|ico)$"
Then: Cache eligible, Edge TTL = 1 month

Nie ustawiaj długiego czasu cache na wszystkie pliki z /public tylko dlatego, że mają rozszerzenie .svg, .png albo .ico. /_next/static/ jest bezpieczne, z racji tego, że Next.js dodaje hash do nazw plików. Publiczne zasoby, takie jak favicon.ico, logo.svg czy baner bez wersji w adresie, mogą zmienić się pod tym samym URL-em. Wtedy potrzebujesz krótszego czasu cache, wersjonowanej nazwy pliku albo czyszczenia cache po wdrożeniu.

4. Wyłączenie cache dla dynamicznych stron

SSR, Server Actions i API nie powinny trafiać do cache Cloudflare bez bardzo przemyślanej konfiguracji. Zacznij od omijania cache dla dynamicznych ścieżek, a cache dla HTML dodawaj dopiero tam, gdzie rozumiesz konsekwencje dla personalizacji, cookies i rewalidacji.

Code
Nazwa: Bypass Dynamic
If: URI Path starts with "/api/" OR
    URI Path starts with "/dashboard/" OR
    URI Path starts with "/admin/" OR
    URI Path starts with "/webhooks/" OR
    Request Method is not in ["GET", "HEAD"]
Then: Bypass cache

W Next.js łatwo przeoczyć, że strony statyczne i ISR zwracają nagłówek Cache-Control z dyrektywą s-maxage, którą CDN może respektować. Ma to sens tylko wtedy, gdy dokładnie wiesz, kiedy różni użytkownicy mogą zobaczyć tę samą wersję HTML-a, a kiedy trzeba ją rozdzielić po cookies, wariantach RSC i rewalidacji. revalidatePath() oraz revalidateTag() odświeżą cache po stronie Next.js, natomiast Cloudflare nadal może trzymać własną kopię HTML do końca ustawionego czasu cache. To jest powodem, by domyślnie zostawić HTML poza dodatkową regułą cache Cloudflare, a jeśli zdecydujesz się go cachować, zsynchronizuj czas cache z rewalidacją Next.js i wpinaj czyszczenie cache CDN w webhook albo proces CI/CD po zmianie treści.

5. Konfiguracja nginx z Cloudflare

Proxy Cloudflare zmienia IP requestu. Bez dodatkowej konfiguracji nginx widzi adres Cloudflare, a nie użytkownika. Napraw to tak:

Zamiast wklejać zakresy IP na sztywno, wygeneruj je skryptem, który pobiera aktualną listę z oficjalnego źródła Cloudflare:

Code
#!/bin/bash
# /usr/local/bin/update-cloudflare-ips.sh
set -euo pipefail
 
TARGET=/etc/nginx/conf.d/cloudflare.conf
TMP=$(mktemp)
 
V4=$(curl -fsS https://www.cloudflare.com/ips-v4)
V6=$(curl -fsS https://www.cloudflare.com/ips-v6)
 
# Nie nadpisuj działającej konfiguracji, jeśli któraś lista jest pusta
[ -n "$V4" ] && [ -n "$V6" ] || { echo "Pusta lista IP, przerywam."; exit 1; }
 
{
  echo "# Zaufane IP Cloudflare. Wygenerowano automatycznie, nie edytuj ręcznie."
  echo "$V4" | sed 's/^/set_real_ip_from /; s/$/;/'
  echo "$V6" | sed 's/^/set_real_ip_from /; s/$/;/'
  echo "real_ip_header CF-Connecting-IP;"
} > "$TMP"
 
mv "$TMP" "$TARGET"
nginx -t && systemctl reload nginx
Code
# crontab -e — odśwież listę raz w tygodniu
0 4 * * 1 /usr/local/bin/update-cloudflare-ips.sh
Code
# /etc/nginx/sites-available/example
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
 
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
 
    # Wspólne nagłówki proxy. Nginx NIE dziedziczy proxy_set_header
    # z bloku nadrzędnego do location, jeśli w danym location pojawi się
    # choć jeden własny proxy_set_header. Dlatego trzymamy je w pliku
    # dołączanym do każdego bloku, zamiast powielać ręcznie.
    # /etc/nginx/snippets/proxy-headers.conf zawiera dyrektywy poniżej.
 
    # Statyczne pliki Next.js z nagłówkami cache
    location /_next/static {
        proxy_pass http://localhost:3000;
        include /etc/nginx/snippets/proxy-headers.conf;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }
 
    # Pozostały ruch proxy do Next.js
    location / {
        proxy_pass http://localhost:3000;
        include /etc/nginx/snippets/proxy-headers.conf;
    }
}
Code
# /etc/nginx/snippets/proxy-headers.conf
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

Co nadal zostaje po Twojej stronie?

Cloudflare rozwiązuje warstwę wejściową: DNS, TLS, cache na serwerach brzegowych i część ochrony przed ruchem automatycznym. Nie zastępuje jednak platformy wdrożeniowej, dlatego przy samodzielnie hostowanym Next.js nadal odpowiadasz za:

  • proces wdrożenia i wycofania błędnej wersji
  • kontrolę zdrowia aplikacji oraz restart po awarii
  • aktualizacje systemu, Node.js, nginx i zależności
  • backupy, logi aplikacji i monitoring błędów
  • strategię dla .next/cache, jeśli uruchamiasz więcej niż jedną instancję

  • przechowywanie uploadów i plików użytkowników poza lokalnym dyskiem VPS-a

To wszystko zostaje po Twojej stronie niezależnie od Cloudflare.

Ochrona DDoS i Bot Management w Cloudflare

Darmowy plan Cloudflare automatycznie chroni przed DDoS. Warto jednak przejrzeć kilka dodatkowych ustawień:

Security Settings w Cloudflare

  • Security Level: Medium (ogranicza ruch z podejrzanych IP)
  • Challenge Passage: 30 minutes (jak długo CAPTCHA jest ważne)
  • Browser Integrity Check: On

Rate Limiting na darmowym planie Cloudflare

W panelu Cloudflare ta funkcja nazywa się Rate Limiting, ale w praktyce chodzi po prostu o ograniczanie liczby żądań z jednego źródła w krótkim czasie. Jest to bardzo przydatne przy API, formularzach i endpointach logowania.

Dashboard → Security → WAF → Rate Limiting Rules:

Code
Nazwa: API Rate Limit
If: URI Path starts with "/api/"
Then: Block for 60 seconds
When: Exceeds 100 requests per 10 seconds from same IP

Bot Fight Mode dla ochrony aplikacji

Dashboard → Security → Bots → Bot Fight Mode: On

Bot Fight Mode pomaga przy prostym ruchu botów, choć nie daje większej kontroli. Przy API, aplikacji mobilnej albo nietypowych integracjach może błędnie wymagać dodatkowej weryfikacji i dlatego lepiej sprawdzają się konkretne reguły WAF i limitowania ruchu.

Optymalizacje wydajności Cloudflare dla Next.js

Minifikacja: dlaczego już jej nie włączasz

Jeśli szukasz w panelu opcji Auto Minify to jej tam nie znajdziesz, ponieważ Cloudflare wycofał ją 5 sierpnia 2024. Stało się to z prostego powodu: nowoczesne narzędzia budują już zminifikowane pliki, a zysk z dodatkowej minifikacji na serwerach brzegowych był prawie żaden, poniżej 0,1% w sieci Cloudflare. Next.js minifikuje JS i CSS w buildzie, więc nic nie tracisz.

Early Hints w Cloudflare

Dashboard → Speed → Optimization → Protocol Optimization:

  • Early Hints: On

Cloudflare wysyła 103 Early Hints z preload linkami, zanim serwer zwróci odpowiedź. Dzięki temu przeglądarka może wcześniej zacząć pobierać CSS i JS.

HTTP/3 (QUIC) w Cloudflare

Dashboard → Network:

  • HTTP/3 (with QUIC): On

To zwykle przyspiesza zestawianie połączeń, szczególnie na urządzeniach mobilnych i mniej stabilnych sieciach.

Monitoring samodzielnie hostowanego Next.js za Cloudflare

Dashboard → Analytics & Logs nie zastąpi Sentry, logów aplikacji ani monitoringu VPS-a, ale daje szybki obraz tego, co dzieje się przed Twoim serwerem. W samodzielnym hostingu warto zaglądać tam po każdym wdrożeniu, większej zmianie cache i nietypowym skoku ruchu.

  1. Web Traffic pokazuje liczbę żądań, transfer, kody odpowiedzi HTTP i kraje, z których przychodzi ruch. Nagły wzrost błędów 5xx zwykle oznacza problem po stronie VPS-a albo nginx. Wzrost 4xx może wskazywać na boty, błędne linki, źle ustawione przekierowania albo zbyt agresywne reguły bezpieczeństwa.
  2. Security Events pokazuje, co Cloudflare zablokował, przepuścił po dodatkowym sprawdzeniu albo ograniczył regułą limitowania ruchu. To dobre miejsce, żeby sprawdzić, czy Bot Fight Mode albo WAF nie utrudnia życia prawdziwym użytkownikom, integracjom i webhookom.
  3. Cache pokazuje, jaka część odpowiedzi została obsłużona z cache Cloudflare. Dla stron mocno statycznych wysoki udział trafień w cache (często powyżej 80%) jest dobrym sygnałem. Naturalnie, w wypadku aplikacji z logowaniem, panelem klienta i personalizacją ten wynik będzie niższy. Ważniejsze jest wtedy to, czy /_next/static/, obrazy i publiczne pliki są serwowane z cache, a HTML i API nie trafiają tam przypadkiem.

Po wdrożeniu sprawdź błędy 5xx, udział odpowiedzi z cache i zdarzenia bezpieczeństwa. Jeśli liczba błędów rośnie, musisz najpierw sprawdzić serwer źródłowy, czyli VPS, nginx i proces Next.js. Z kolei, jeśli cache nagle spada, zweryfikuj reguły Cloudflare oraz nagłówki Cache-Control. Jeśli pojawia się dużo blokad bezpieczeństwa, przejrzyj konkretne ścieżki i adresy IP, zanim zdecydujesz się na globalne zaostrzenie reguł.

Audyt techniczny i optymalizacja pod kątem SEO i GEO.
Audyt techniczny SEO

Często zadawane pytania

Czy cache Cloudflare nie koliduje z ISR?

Nie, o ile rozumiesz, która warstwa odpowiada za świeżość treści. Najbezpieczniej mocno cache'ować tylko statyczne pliki z /_next/static/, a HTML zostawić pod kontrolą Next.js. CDN może cachować strony statyczne i ISR, jeśli respektuje s-maxage i stale-while-revalidate, ale rewalidacja na żądanie (revalidatePath(), revalidateTag()) czyści cache Next.js, nie cache Cloudflare. W takim modelu musisz dopiąć czyszczenie cache CDN dla konkretnych adresów albo zaakceptować, że serwer brzegowy Cloudflare odda starą wersję do końca ustawionego czasu cache.

Czy darmowy plan Cloudflare wystarcza na produkcję?

Dla wielu stron usługowych i małych aplikacji w zupełności. Dostajesz DNS, proxy, globalny CDN, podstawową ochronę DDoS, SSL i Cache Rules, co pokrywa większość realnych potrzeb. Przy większym ruchu, bardziej zaawansowanym WAF, precyzyjnym zarządzaniu botami, wielu regułach cache albo intensywnym użyciu Workers warto sprawdzić aktualne limity planu i rozważyć wersję płatną. Zacznij od darmowego, a płatny dokładaj, gdy realnie uderzysz w jego ograniczenia.

Jak wyczyścić cache Cloudflare po wdrożeniu?

Najprościej z panelu: Caching → Purge Cache → Custom Purge i wskazanie ścieżki, np. /_next/*. W praktyce lepiej zautomatyzować to w procesie CI/CD. Po każdym udanym wdrożeniu wywołaj czyszczenie cache przez API Cloudflare, żeby nie polegać na ręcznym kroku. Pliki z /_next/static/ zwykle nie wymagają takiego czyszczenia, bo Next.js dodaje do ich nazw hash zawartości. Nowy build oznacza więc nowe nazwy plików, a ręczne czyszczenie jest potrzebne głównie dla cache'owanego HTML.

Dlaczego trzeba konfigurować prawdziwe IP klienta w nginx?

Bo gdy ruch przechodzi przez proxy Cloudflare, Twój serwer w nagłówku połączenia widzi adres IP Cloudflare, a nie użytkownika. Bez korekty logi, limitowanie ruchu i wszelka logika zależna od IP operowałyby na adresach Cloudflare, przez co byłyby bezużyteczne. Dyrektywy set_real_ip_from (zakresy Cloudflare) plus real_ip_header CF-Connecting-IP mówią nginx, by odczytał prawdziwy adres klienta z nagłówka dodawanego przez Cloudflare. Pamiętaj, że listę zakresów IP Cloudflare trzeba okresowo odświeżać z oficjalnego źródła.

Kiedy samodzielne hostowanie z Cloudflare ma sens zamiast Vercel?

Gdy zależy Ci na niższych i przewidywalnych kosztach przy większym ruchu, na pełnej kontroli nad infrastrukturą albo na specyficznych wymaganiach, których platforma nie pokrywa. Cloudflare na darmowym planie dokłada wtedy przed VPS-em solidną warstwę CDN, SSL i ochrony DDoS. Trzeba jednak uczciwie policzyć drugą stronę: bierzesz na siebie utrzymanie serwera, wdrożenia, odnawianie certyfikatów, monitoring i reagowanie na incydenty. To realna alternatywa dla Vercel, ale nie darmowy odpowiednik bez kosztu Twojego czasu.

O autorze

Maciej Sala

Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwijam własne projekty.

Pomagam przekładać takie tematy na konkretne wdrożenia w frontendzie, SEO, analityce i procesie produktowym.

Skontaktuj się ze mną

Biblioteka wiedzy

Czytaj dalej

Zobacz więcej wpisów
Astro i Cloudflare Workers — wdrożenie, bindings i lokalne środowisko programistyczne

Astro i Cloudflare Workers bardzo dobrze do siebie pasują. Z jednej strony szybki HTML, globalna infrastruktura na brzegu sieci, niskie koszty, z drugiej strony, środowisko wykonawcze, które możesz uruchomić lokalnie. Brzmi prosto, ale diabeł tkwi w bindings, limitach CPU oraz konfiguracji Wranglera. Pokażę Ci konfigurację od adaptera po KV, R2 i D1.

Maciej Sala

Maciej Sala

Founder StriveLab

Koszty utrzymania Astro i Cloudflare: kiedy statyczna strona jest tańsza niż WordPress

Faktura za hosting to czubek góry lodowej. Pod nią: aktualizacje wtyczek, konflikty wersji, incydenty bezpieczeństwa w niedzielę o 23:00, regresy po każdym update i czas programisty, który sprawdza, czy formularz nadal wysyła maile. TCO WordPressa jest zawsze wyższe niż wygląda na początku.

Maciej Sala

Maciej Sala

Founder StriveLab

Backend dla frontendowca: cache, deployment i bezpieczeństwo

To trzecia część serii „Backend dla frontendowca”. Po fundamentach API oraz tematach real-time, webhooków i uwierzytelniania zostaje warstwa, która decyduje o tym, czy aplikacja wytrzyma prawdziwe użytkowanie: cache , kolejki, pliki, deployment, monitoring i bezpieczeństwo .

Maciej Sala

Maciej Sala

Founder StriveLab