Last active
March 24, 2025 09:01
-
-
Save mklooss/fb373cdb7e9b47312811c1e04de3d7f7 to your computer and use it in GitHub Desktop.
shopware 6 varnish sample config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| apt update | |
| apt install varnish varnish-modules -y |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| server { | |
| listen 127.0.0.1:8080; | |
| index index.php index.html; | |
| server_name varnish.default.tld; | |
| root /home/USER/htdocs/public/; | |
| location /recovery/install { | |
| index index.php; | |
| try_files $uri /recovery/install/index.php$is_args$args; | |
| } | |
| location /recovery/update/ { | |
| location /recovery/update/assets { | |
| } | |
| if (!-e $request_filename){ | |
| rewrite . /recovery/update/index.php last; | |
| } | |
| } | |
| location / { | |
| try_files $uri /index.php$is_args$args; | |
| } | |
| location ~ \.php$ { | |
| fastcgi_split_path_info ^(.+\.php)(/.+)$; | |
| include /etc/nginx/fastcgi_params; | |
| fastcgi_param HTTP_PROXY ""; | |
| fastcgi_buffers 8 16k; | |
| fastcgi_buffer_size 32k; | |
| client_max_body_size 24M; | |
| client_body_buffer_size 128k; | |
| fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
| fastcgi_pass unix:/var/run/php7.4-fpm.sock; | |
| http2_push_preload on; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| server { | |
| listen 80; | |
| listen [::]:80; | |
| server_name varnish.default.tld; | |
| return 301 https://$server_name$request_uri; | |
| } | |
| server { | |
| listen 443 ssl http2; | |
| listen [::]:443 ssl http2; | |
| server_name varnish.default.tld; | |
| # Server certificate and key. | |
| ssl_certificate /opt/cert/self/server.cert; | |
| ssl_certificate_key /opt/cert/self/server.key; | |
| location = /robots.txt { | |
| add_header Content-Type text/plain; | |
| return 200 "User-agent: *\nDisallow: /\n"; | |
| } | |
| location / { | |
| # Forward request to Varnish. | |
| proxy_pass http://127.0.0.1:6081; | |
| 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_hide_header Via; | |
| proxy_redirect off; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/packages/framework.yaml | |
| --- | |
| framework: | |
| trusted_proxies: '%env(TRUSTED_PROXIES)%' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/packages/prod/varnish.yaml | |
| --- | |
| shopware: | |
| http_cache: | |
| reverse_proxy: | |
| enabled: true | |
| use_varnish_xkey: true | |
| hosts: | |
| - 127.0.0.1:6081 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .env in Shopware dir | |
| SHOPWARE_HTTP_CACHE_ENABLED=1 | |
| TRUSTED_PROXIES=127.0.0.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Unit] | |
| Description=Varnish Cache, a high-performance HTTP accelerator | |
| Documentation=https://www.varnish-cache.org/docs/ man:varnishd | |
| [Service] | |
| Type=simple | |
| # Maximum number of open files (for ulimit -n) | |
| LimitNOFILE=131072 | |
| # Locked shared memory - should suffice to lock the shared memory log | |
| # (varnishd -l argument) | |
| # Default log size is 80MB vsl + 1M vsm + header -> 82MB | |
| # unit is bytes | |
| LimitMEMLOCK=85983232 | |
| Environment=LD_PRELOAD=/opt/lib/libmimalloc.so | |
| ExecStart=/usr/sbin/varnishd \ | |
| -j unix,user=vcache \ | |
| -F \ | |
| -a :6081 \ | |
| -T localhost:6082 \ | |
| -p thread_pool_min=10 \ | |
| -p thread_pool_max=500 \ | |
| -p http_resp_hdr_len=65536 \ | |
| -p http_resp_size=98304 \ | |
| -p workspace_backend=320k \ | |
| -p workspace_client=320k \ | |
| -f /etc/varnish/default.vcl \ | |
| -S /etc/varnish/secret \ | |
| -s Cache=malloc,12g \ | |
| -s Transient=malloc,512m | |
| ExecReload=/usr/share/varnish/varnishreload | |
| ProtectSystem=full | |
| ProtectHome=true | |
| PrivateTmp=true | |
| PrivateDevices=true | |
| [Install] | |
| WantedBy=multi-user.target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| vcl 4.1; | |
| import std; | |
| import xkey; | |
| import cookie; | |
| # Specify your app nodes here. Use round-robin balancing to add more than one. | |
| backend default { | |
| .host = "127.0.0.1"; | |
| .port = "8080"; | |
| } | |
| # ACL for purgers IP. (This needs to contain app server ips) | |
| acl purgers { | |
| "127.0.0.1"; | |
| "localhost"; | |
| "::1"; | |
| } | |
| sub vcl_recv { | |
| if (req.restarts > 0) { | |
| set req.hash_always_miss = true; | |
| } | |
| # Handle PURGE | |
| if (req.method == "PURGE") { | |
| if (client.ip !~ purgers) { | |
| return (synth(403, "Forbidden")); | |
| } | |
| if (req.http.xkey) { | |
| set req.http.n-gone = xkey.purge(req.http.xkey); | |
| return (synth(200, "Invalidated "+req.http.n-gone+" objects")); | |
| } else { | |
| return (purge); | |
| } | |
| } | |
| # Handle BAN | |
| if (req.method == "BAN") { | |
| if (!client.ip ~ purgers) { | |
| return (synth(403, "Forbidden")); | |
| } | |
| ban("req.url ~ "+req.url); | |
| return (synth(200, "BAN URLs containing (" + req.url + ") done.")); | |
| } | |
| # 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); | |
| } | |
| if (req.http.Authorization) { | |
| return (pass); | |
| } | |
| # We only deal with GET and HEAD by default | |
| if (req.method != "GET" && req.method != "HEAD") { | |
| return (pass); | |
| } | |
| # Always pass these paths directly to php without caching | |
| # Note: virtual URLs might bypass this rule (e.g. /en/checkout) | |
| if (req.url ~ "^/(checkout|account|admin|api)(/.*)?$") { | |
| return (pass); | |
| } | |
| # Mitigate httpoxy application vulnerability, see: https://httpoxy.org/ | |
| unset req.http.Proxy; | |
| cookie.parse(req.http.cookie); | |
| set req.http.cache-hash = cookie.get("sw-cache-hash"); | |
| set req.http.currency = cookie.get("sw-currency"); | |
| set req.http.states = cookie.get("sw-states"); | |
| if (req.url == "/widgets/checkout/info" && !req.http.states ~ "cart-filled") { | |
| return (synth(204, "")); | |
| } | |
| # Strip query strings only needed by browser javascript. Customize to used tags. | |
| if (req.url ~ "(\?|&)(_bta_c|_bta_tid|_ga|_ke|adgid|adgroupid|adid|awcpk_campaign|camid|campaignid|chl|cof|cx|dm_i|dv|ef_id|epik|fb_action_ids|fb_action_types|fb_source|fbclid|gad_source|gclid|gclsrc|gdffi|gdfms|gdftrk|ie|kw|kwid|matomo_campaign|matomo_cid|matomo_content|matomo_group|matomo_keyword|matomo_kwd|matomo_medium|matomo_placement|matomo_source|mc_cid|mc_eid|mkwid|msclkid|mtm_campaign|mtm_cid|mtm_content|mtm_group|mtm_keyword|mtm_kwd|mtm_medium|mtm_placement|mtm_source|nk|pa|pcrid|piwik_campaign|piwik_kwd|pixelId|pk_campaign|pk_keyword|pk_kwd|pp|redirect_log_mongo_id|redirect_mongo_id|s_kwcid|sb_referer_host|siteurl|sv1|sv_campaign_id|trk_contact|trk_module|trk_msg|trk_sid|srsltid|utm_[a-z]+)=") { | |
| # see rfc3986#section-2.3 "Unreserved Characters" for regex | |
| set req.url = regsuball(req.url, "(_bta_c|_bta_tid|_ga|_ke|adgid|adgroupid|adid|awcpk_campaign|camid|campaignid|chl|cof|cx|dm_i|dv|ef_id|epik|fb_action_ids|fb_action_types|fb_source|fbclid|gad_source|gclid|gclsrc|gdffi|gdfms|gdftrk|ie|kw|kwid|matomo_campaign|matomo_cid|matomo_content|matomo_group|matomo_keyword|matomo_kwd|matomo_medium|matomo_placement|matomo_source|mc_cid|mc_eid|mkwid|msclkid|mtm_campaign|mtm_cid|mtm_content|mtm_group|mtm_keyword|mtm_kwd|mtm_medium|mtm_placement|mtm_source|nk|pa|pcrid|piwik_campaign|piwik_kwd|pixelId|pk_campaign|pk_keyword|pk_kwd|pp|redirect_log_mongo_id|redirect_mongo_id|s_kwcid|sb_referer_host|siteurl|sv1|sv_campaign_id|trk_contact|trk_module|trk_msg|trk_sid|srsltid|utm_[a-z]+)=[A-Za-z0-9\-\_\.\~]+&?", ""); | |
| } | |
| set req.url = regsub(req.url, "(\?|\?&|&)$", ""); | |
| # Normalize query arguments | |
| set req.url = std.querysort(req.url); | |
| # Set a header announcing Surrogate Capability to the origin | |
| set req.http.Surrogate-Capability = "shopware=ESI/1.0"; | |
| # Make sure that the client ip is forward to the client. | |
| if (req.http.x-forwarded-for) { | |
| set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; | |
| } else { | |
| set req.http.X-Forwarded-For = client.ip; | |
| } | |
| return (hash); | |
| } | |
| sub vcl_hash { | |
| # Consider Shopware HTTP cache cookies | |
| if (req.http.cache-hash != "") { | |
| hash_data("+context=" + req.http.cache-hash); | |
| } elseif (req.http.currency != "") { | |
| hash_data("+currency=" + req.http.currency); | |
| } | |
| } | |
| sub vcl_hit { | |
| # Consider client states for response headers | |
| if (req.http.states) { | |
| if (req.http.states ~ "logged-in" && obj.http.sw-invalidation-states ~ "logged-in" ) { | |
| return (pass); | |
| } | |
| if (req.http.states ~ "cart-filled" && obj.http.sw-invalidation-states ~ "cart-filled" ) { | |
| return (pass); | |
| } | |
| } | |
| } | |
| sub vcl_backend_fetch { | |
| unset bereq.http.cache-hash; | |
| unset bereq.http.currency; | |
| unset bereq.http.states; | |
| } | |
| sub vcl_backend_response { | |
| # Serve stale content for three days after object expiration | |
| set beresp.grace = 3d; | |
| unset beresp.http.X-Powered-By; | |
| unset beresp.http.Server; | |
| if (beresp.http.Surrogate-Control ~ "ESI/1.0") { | |
| unset beresp.http.Surrogate-Control; | |
| set beresp.do_esi = true; | |
| return (deliver); | |
| } | |
| if (bereq.url ~ "\.js$" || beresp.http.content-type ~ "text") { | |
| set beresp.do_stream = false; | |
| } | |
| if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) { | |
| unset beresp.http.Set-Cookie; | |
| } | |
| } | |
| sub vcl_deliver { | |
| ## we don't want the client to cache | |
| if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(theme|media|thumbnail|bundles)/") { | |
| 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"; | |
| } | |
| # invalidation headers are only for internal use | |
| unset resp.http.sw-invalidation-states; | |
| unset resp.http.xkey; | |
| unset resp.http.X-Varnish; | |
| unset resp.http.Via; | |
| unset resp.http.Link; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment