I recently configured my magenot2 site with cloudflare, and it is working fine on free plan,I am facing an issue, when I try to configure varnish for full page cache, it gives too many redirect error,
Below are my nginx conf file and default.vcl files
/etc/nginx/sites-available/mysite
server {
listen 8080;
server_name myexamplesite.com;
set $MAGE_ROOT /var/www/mysite;
set $MAGE_DEBUG_SHOW_ARGS 0;
# include /vagrant/magento2/nginx.conf.sample;
root $MAGE_ROOT/pub;
index index.php;
autoindex off;
charset UTF-8;
error_page 404 403 = /errors/404.php;
#add_header "X-UA-Compatible" "IE=Edge";
# Deny access to sensitive files
location /.user.ini {
deny all;
}
# phpMyAdmin location
location /phpmyadmin {
root /usr/share;
index index.php;
try_files $uri $uri/ =404;
}
location ~ ^/phpmyadmin/(.*.php)$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # PHP 8.1 FPM socket
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin/$1;
include fastcgi_params;
# Increase timeouts
fastcgi_read_timeout 300; # Increase timeout to 300 seconds (5 minutes)
}
location ~ ^/phpmyadmin/.*.conf$ {
deny all;
}
# PHP entry point for setup application
location ~* ^/setup($|/) {
root $MAGE_ROOT;
location ~ ^/setup/index.php {
fastcgi_pass fastcgi_backend;
fastcgi_param PHP_FLAG "session.auto_start=off n suhosin.session.cryptua=off";
fastcgi_param PHP_VALUE "memory_limit=756M n max_execution_time=600";
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/setup/(?!pub/). {
deny all;
}
location ~ ^/setup/pub/ {
add_header X-Frame-Options "SAMEORIGIN";
}
}
# PHP entry point for update application
location ~* ^/update($|/) {
root $MAGE_ROOT;
location ~ ^/update/index.php {
fastcgi_split_path_info ^(/update/index.php)(/.+)$;
fastcgi_pass fastcgi_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
# Deny everything but index.php
location ~ ^/update/(?!pub/). {
deny all;
}
location ~ ^/update/pub/ {
add_header X-Frame-Options "SAMEORIGIN";
}
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location /pub/ {
location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*.xml) {
deny all;
}
alias $MAGE_ROOT/pub/;
add_header X-Frame-Options "SAMEORIGIN";
}
location /static/ {
# Uncomment the following line in production mode
# expires max;
expires 1y;
add_header Cache-Control "public, max-age=31536000";
# Remove signature of the static files that is used to overcome the browser cache
location ~ ^/static/versiond*/ {
rewrite ^/static/versiond*/(.*)$ /static/$1 last;
}
location ~* .(ico|jpg|jpeg|png|gif|svg|svgz|webp|avif|avifs|js|css|eot|ttf|otf|woff|woff2|html|json|webmanifest)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
if (!-f $request_filename) {
rewrite ^/static/(versiond*/)?(.*)$ /static.php?resource=$2 last;
}
}
location ~* .(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
if (!-f $request_filename) {
rewrite ^/static/(versiond*/)?(.*)$ /static.php?resource=$2 last;
}
}
if (!-f $request_filename) {
rewrite ^/static/(versiond*/)?(.*)$ /static.php?resource=$2 last;
}
add_header X-Frame-Options "SAMEORIGIN";
}
location /media/ {
try_files $uri $uri/ /get.php$is_args$args;
location ~ ^/media/theme_customization/.*.xml {
deny all;
}
location ~* .(ico|jpg|jpeg|png|gif|svg|svgz|webp|avif|avifs|js|css|eot|ttf|otf|woff|woff2)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
try_files $uri $uri/ /get.php$is_args$args;
}
location ~* .(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
try_files $uri $uri/ /get.php$is_args$args;
}
add_header X-Frame-Options "SAMEORIGIN";
}
location /media/customer/ {
deny all;
}
location /media/downloadable/ {
deny all;
}
location /media/import/ {
deny all;
}
location /media/custom_options/ {
deny all;
}
location /errors/ {
location ~* .xml$ {
deny all;
}
}
# PHP entry point for main application
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check).php$ {
try_files $uri =404;
fastcgi_pass fastcgi_backend;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param PHP_FLAG "session.auto_start=off n suhosin.session.cryptua=off";
fastcgi_param PHP_VALUE "memory_limit=756M n max_execution_time=18000";
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
image/svg+xml;
gzip_vary on;
# Banned locations (only reached if the earlier PHP entry point regexes don't match)
location ~* (.php$|.phtml$|.htaccess$|.htpasswd$|.git) {
deny all;
}
location ^~ /.well-known/acme-challenge/ {
root /var/www/html; # or your actual web root
default_type "text/plain";
try_files $uri =404;
}
# listen 443 ssl; # managed by Certbot
# ssl_certificate /etc/letsencrypt/live/testing.toneart-shop.de/fullchain.pem; # managed by Certbot
# ssl_certificate_key /etc/letsencrypt/live/testing.toneart-shop.de/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# --------------------
# HTTPS Frontend (SSL + proxy to Varnish)
# --------------------
server {
listen 443 ssl http2;
server_name myexamplesite.com;
ssl_certificate /etc/letsencrypt/live/myexamplesite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myexamplesite.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
proxy_buffers 16 64k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
location / {
proxy_pass http://127.0.0.1:80;
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 https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header SSL-Offloaded https;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
}
}
default.vcl
vcl 4.1;
import std;
backend default {
.host = "localhost";
.port = "8080";
.first_byte_timeout = 600s;
}
# Add hostnames, IP addresses and subnets that are allowed to purge content
acl purge {
"localhost";
"127.0.0.1";
"::1";
}
sub vcl_recv {
# Remove empty query string parameters
# e.g.: www.example.com/index.html?
if (req.url ~ "?$") {
set req.url = regsub(req.url, "?$", "");
}
# Remove port number from host header
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Sorts query string parameters alphabetically for cache normalization purposes
set req.url = std.querysort(req.url);
# Remove the proxy header to mitigate the httpoxy vulnerability
# See https://httpoxy.org/
unset req.http.proxy;
# Add X-Forwarded-Proto header when using https
if (!req.http.X-Forwarded-Proto) {
if(std.port(server.ip) == 443 || std.port(server.ip) == 8443) {
set req.http.X-Forwarded-Proto = "https";
} else {
set req.http.X-Forwarded-Proto = "http";
}
}
# Reduce grace to 300s if the backend is healthy
# In case of an unhealthy backend, the original grace is used
if (std.healthy(req.backend_hint)) {
set req.grace = 300s;
}
# Purge logic to remove objects from the cache
# Tailored to Magento's cache invalidation mechanism
# The X-Magento-Tags-Pattern value is matched to the tags in the X-Magento-Tags header
# If X-Magento-Tags-Pattern is not set, a URL-based purge is executed
if (req.method == "PURGE") {
if (client.ip !~ purge) {
return (synth(405, "Method not allowed"));
}
if (!req.http.X-Magento-Tags-Pattern) {
return (purge);
}
ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
return (synth(200, "Purged"));
}
# Only handle relevant HTTP request methods
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "PATCH" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
return (pipe);
}
# Only cache GET and HEAD requests
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Don't cache the health check page
if (req.url ~ "^/(pub/)?(health_check.php)$") {
return (pass);
}
# Collapse multiple cookie headers into one
std.collect(req.http.Cookie);
# Remove tracking query string parameters used by analytics tools
if (req.url ~ "(?|&)(_branch_match_id|_bta_[a-z]+|_bta_c|_bta_tid|_ga|_gl|_ke|_kx|campid|cof|customid|cx|dclid|dm_i|ef_id|epik|fbclid|gad_source|gbraid|gclid|gclsrc|gdffi|gdfms|gdftrk|hsa_acc|hsa_ad|hsa_cam|hsa_grp|hsa_kw|hsa_mt|hsa_net|hsa_src|hsa_tgt|hsa_ver|ie|igshid|irclickid|matomo_campaign|matomo_cid|matomo_content|matomo_group|matomo_keyword|matomo_medium|matomo_placement|matomo_source|mc_[a-z]+|mc_cid|mc_eid|mkcid|mkevt|mkrid|mkwid|msclkid|mtm_campaign|mtm_cid|mtm_content|mtm_group|mtm_keyword|mtm_medium|mtm_placement|mtm_source|nb_klid|ndclid|origin|pcrid|piwik_campaign|piwik_keyword|piwik_kwd|pk_campaign|pk_keyword|pk_kwd|redirect_log_mongo_id|redirect_mongo_id|rtid|s_kwcid|sb_referer_host|sccid|si|siteurl|sms_click|sms_source|sms_uph|srsltid|toolid|trk_contact|trk_module|trk_msg|trk_sid|ttclid|twclid|utm_[a-z]+|utm_campaign|utm_content|utm_creative_format|utm_id|utm_marketing_tactic|utm_medium|utm_source|utm_source_platform|utm_term|vmcid|wbraid|yclid|zanpid)=") {
set req.url = regsuball(req.url, "(_branch_match_id|_bta_[a-z]+|_bta_c|_bta_tid|_ga|_gl|_ke|_kx|campid|cof|customid|cx|dclid|dm_i|ef_id|epik|fbclid|gad_source|gbraid|gclid|gclsrc|gdffi|gdfms|gdftrk|hsa_acc|hsa_ad|hsa_cam|hsa_grp|hsa_kw|hsa_mt|hsa_net|hsa_src|hsa_tgt|hsa_ver|ie|igshid|irclickid|matomo_campaign|matomo_cid|matomo_content|matomo_group|matomo_keyword|matomo_medium|matomo_placement|matomo_source|mc_[a-z]+|mc_cid|mc_eid|mkcid|mkevt|mkrid|mkwid|msclkid|mtm_campaign|mtm_cid|mtm_content|mtm_group|mtm_keyword|mtm_medium|mtm_placement|mtm_source|nb_klid|ndclid|origin|pcrid|piwik_campaign|piwik_keyword|piwik_kwd|pk_campaign|pk_keyword|pk_kwd|redirect_log_mongo_id|redirect_mongo_id|rtid|s_kwcid|sb_referer_host|sccid|si|siteurl|sms_click|sms_source|sms_uph|srsltid|toolid|trk_contact|trk_module|trk_msg|trk_sid|ttclid|twclid|utm_[a-z]+|utm_campaign|utm_content|utm_creative_format|utm_id|utm_marketing_tactic|utm_medium|utm_source|utm_source_platform|utm_term|vmcid|wbraid|yclid|zanpid)=[-_A-z0-9+(){}%.*]+&?", "");
set req.url = regsub(req.url, "[?|&]+$", "");
}
# Don't cache the authenticated GraphQL requests
if (req.url ~ "/graphql" && req.http.Authorization ~ "^Bearer") {
return (pass);
}
return (hash);
}
sub vcl_hash {
# Add a cache variation based on the X-Magento-Vary cookie, but not for graphql requests
if (req.url !~ "/graphql" && req.http.cookie ~ "X-Magento-Vary=") {
hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "1"));
}
# Create cache variations depending on the request protocol
hash_data(req.http.X-Forwarded-Proto);
if (req.url ~ "/graphql") {
# Create cache variations based on the cache ID that is set by Magento
if (req.http.X-Magento-Cache-Id) {
hash_data(req.http.X-Magento-Cache-Id);
} else {
# If no X-Magento-Cache-Id header is set, use the store and currency values to vary on
hash_data(req.http.Store);
hash_data(req.http.Content-Currency);
}
}
}
sub vcl_backend_response {
# Serve stale content for three days after object expiration
# Perform asynchronous revalidation while stale content is served
set beresp.grace = 3d;
# All text-based content can be parsed as ESI
if (beresp.http.content-type ~ "text") {
set beresp.do_esi = true;
}
# Allow GZIP compression on all JavaScript files and all text-based content
if (bereq.url ~ ".js$" || beresp.http.content-type ~ "text") {
set beresp.do_gzip = true;
}
# Add debug headers
if (beresp.http.X-Magento-Debug) {
set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
}
# Only cache HTTP 200 and HTTP 404 responses
if (beresp.status != 200 && beresp.status != 404) {
set beresp.ttl = 120s;
set beresp.uncacheable = true;
return (deliver);
}
# Don't cache if the request cache ID doesn't match the response cache ID for graphql requests
if (bereq.url ~ "/graphql" && bereq.http.X-Magento-Cache-Id && bereq.http.X-Magento-Cache-Id != beresp.http.X-Magento-Cache-Id) {
set beresp.ttl = 120s;
set beresp.uncacheable = true;
return (deliver);
}
# Remove the Set-Cookie header for cacheable content
# Only for HTTP GET & HTTP HEAD requests
if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
unset beresp.http.Set-Cookie;
}
}
sub vcl_deliver {
# Add debug headers
if (resp.http.X-Magento-Debug) {
if (obj.uncacheable) {
set resp.http.X-Magento-Cache-Debug = "UNCACHEABLE";
} else if (obj.hits) {
set resp.http.X-Magento-Cache-Debug = "HIT";
set resp.http.Grace = req.http.grace;
} else {
set resp.http.X-Magento-Cache-Debug = "MISS";
}
} else {
unset resp.http.Age;
}
# Don't let browser cache non-static files
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}
# Cleanup headers
}
There is another site setup on same server which is not cloudflare , varnish works fine on that site.Can anyone please let me know how to fix this issue.