Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9ea3671

Browse files
committed
Rewrite the varnish cookbook article
1 parent 7dcce1b commit 9ea3671

File tree

1 file changed

+96
-171
lines changed

1 file changed

+96
-171
lines changed

cookbook/cache/varnish.rst

Lines changed: 96 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,102 @@ How to Use Varnish to Speed up my Website
77
Because Symfony's cache uses the standard HTTP cache headers, the
88
:ref:`symfony-gateway-cache` can easily be replaced with any other reverse
99
proxy. `Varnish`_ is a powerful, open-source, HTTP accelerator capable of serving
10-
cached content quickly and including support for :ref:`Edge Side Includes <edge-side-includes>`.
10+
cached content fast and including support for :ref:`Edge Side Includes <edge-side-includes>`.
1111

12-
Trusting Reverse Proxies
13-
------------------------
12+
.. index::
13+
single: Varnish; configuration
14+
15+
Make Symfony Trust the Reverse Proxy
16+
------------------------------------
1417

1518
For ESI to work correctly and for the :ref:`X-FORWARDED <varnish-x-forwarded-headers>`
1619
headers to be used, you need to configure Varnish as a
1720
:doc:`trusted proxy </cookbook/request/load_balancer_reverse_proxy>`.
1821

19-
.. index::
20-
single: Varnish; configuration
22+
.. _varnish-x-forwarded-headers:
23+
24+
Routing and X-FORWARDED Headers
25+
-------------------------------
26+
27+
To ensure that the Symfony Router generates URLs correctly with Varnish,
28+
a ``X-Forwarded-Port`` header must be present for Symfony to use the
29+
correct port number.
30+
31+
This port depends on your setup. Lets say that external connections come in
32+
on the default HTTP port 80. For HTTPS connections, there is another proxy
33+
(as Varnish does not do HTTPS itself) on the default HTTPS port 443 that
34+
handles the SSL termination and forwards the requests as HTTP requests to
35+
Varnish with a ``X-Forwarded-Proto`` header. In this case, you need to add
36+
the following configuration snippet:
37+
38+
.. code-block:: varnish4
39+
40+
sub vcl_recv {
41+
if (req.http.X-Forwarded-Proto == "https" ) {
42+
set req.http.X-Forwarded-Port = "443";
43+
} else {
44+
set req.http.X-Forwarded-Port = "80";
45+
}
46+
}
47+
48+
.. note::
49+
50+
Remember to configure :ref:`framework.trusted_proxies <reference-framework-trusted-proxies>`
51+
in the Symfony configuration so that Varnish is seen as a trusted proxy
52+
and the ``X-Forwarded-*`` headers are used.
53+
54+
Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves
55+
the ``X-Forwarded-Proto`` header in the request. If you do not configure
56+
Varnish as trusted proxy, Symfony will see all requests as coming through
57+
insecure HTTP connections from the Varnish host instead of the real client.
2158

22-
Configuration
23-
-------------
59+
If the ``X-Forwarded-Port`` header is not set correctly, Symfony will append
60+
the port where the PHP application is running when generating absolute URLs,
61+
e.g. ``http://example.com:8080/my/path``.
2462

25-
As seen previously, Symfony is smart enough to detect whether it talks to a
26-
reverse proxy that understands ESI or not. It works out of the box when you
27-
use the Symfony reverse proxy, but you need a special configuration to make
28-
it work with Varnish. Thankfully, Symfony relies on yet another standard
29-
written by Akamai (`Edge Architecture`_), so the configuration tips in this
30-
chapter can be useful even if you don't use Symfony.
63+
Ensure Consistent Caching Behaviour
64+
-----------------------------------
65+
66+
Varnish uses the cache headers sent by your application to determine how
67+
to cache content. However, versions prior to Varnish 4 did not respect
68+
``Cache-Control: no-cache``. To ensure consistent behaviour, use the following
69+
configuration if you are still using Varnish 3:
70+
71+
.. configuration-block::
72+
73+
.. code-block:: varnish3
74+
75+
sub vcl_fetch {
76+
/* By default, Varnish3 ignores Cache-Control: no-cache and private
77+
https://www.varnish-cache.org/docs/3.0/tutorial/increasing_your_hitrate.html#cache-control
78+
*/
79+
if (beresp.http.Cache-Control ~ "no-cache" ||
80+
beresp.http.Cache-Control ~ "private"
81+
) {
82+
return (hit_for_pass);
83+
}
84+
}
85+
86+
.. code-block:: varnish2
87+
88+
sub vcl_fetch {
89+
// By default, Varnish2 ignores Pragma: nocache and Cache-Control: no-cache and private
90+
if (beresp.http.Cache-Control ~ "no-cache" ||
91+
beresp.http.Cache-Control ~ "private"
92+
) {
93+
return (hit_for_pass);
94+
}
95+
}
96+
97+
Enable Edge Side Includes (ESI)
98+
-------------------------------
99+
100+
As explained in the :ref:`Edge Side Includes section<edge-side-includes>`,
101+
Symfony detects whether it talks to a reverse proxy that understands ESI or
102+
not. When you use the Symfony reverse proxy, you don't need to do anything.
103+
But to make Varnish instead of Symfony resolve the ESI tags, you need some
104+
configuration in Varnish. Symfony uses the ``Surrogate-Capability`` header
105+
from the `Edge Architecture`_ described by Akamai.
31106

32107
.. note::
33108

@@ -58,22 +133,12 @@ Symfony adds automatically:
58133

59134
.. code-block:: varnish4
60135
61-
/* (https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#req-not-available-in-vcl-backend-response) */
62136
sub vcl_backend_response {
63137
// Check for ESI acknowledgement and remove Surrogate-Control header
64138
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
65139
unset beresp.http.Surrogate-Control;
66140
set beresp.do_esi = true;
67141
}
68-
/* By default Varnish ignores Pragma: nocache
69-
(https://www.varnish-cache.org/docs/4.0/users-guide/increasing-your-hitrate.html#cache-control)
70-
so in order avoid caching it has to be done explicitly */
71-
if (beresp.http.Pragma ~ "no-cache") {
72-
// https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#hit-for-pass-objects-are-created-using-beresp-uncacheable
73-
set beresp.uncacheable = true;
74-
set beresp.ttl = 120s;
75-
return (deliver);
76-
}
77142
}
78143
79144
.. code-block:: varnish3
@@ -84,14 +149,6 @@ Symfony adds automatically:
84149
unset beresp.http.Surrogate-Control;
85150
set beresp.do_esi = true;
86151
}
87-
/* By default Varnish ignores Cache-Control: nocache
88-
(https://www.varnish-cache.org/docs/3.0/tutorial/increasing_your_hitrate.html#cache-control),
89-
so in order avoid caching it has to be done explicitly */
90-
if (beresp.http.Pragma ~ "no-cache" ||
91-
beresp.http.Cache-Control ~ "no-cache" ||
92-
beresp.http.Cache-Control ~ "private") {
93-
return (hit_for_pass);
94-
}
95152
}
96153
97154
.. code-block:: varnish2
@@ -102,13 +159,6 @@ Symfony adds automatically:
102159
unset beresp.http.Surrogate-Control;
103160
esi;
104161
}
105-
/* By default Varnish ignores Cache-Control: nocache
106-
so in order avoid caching it has to be done explicitly */
107-
if (beresp.http.Pragma ~ "no-cache" ||
108-
beresp.http.Cache-Control ~ "no-cache" ||
109-
beresp.http.Cache-Control ~ "private") {
110-
return (hit_for_pass);
111-
}
112162
}
113163
114164
.. caution::
@@ -117,6 +167,12 @@ Symfony adds automatically:
117167
(read `GZIP and Varnish`_). If you're not using Varnish 3.0, put a web
118168
server in front of Varnish to perform the compression.
119169

170+
.. tip::
171+
172+
If you followed the advice about ensuring a consistent caching
173+
behaviour, those vcl functions already exist. Just append the code
174+
to the end of the function, they won't interfere with each other.
175+
120176
.. index::
121177
single: Varnish; Invalidation
122178

@@ -134,139 +190,8 @@ proxy before it has expired, it adds complexity to your caching setup.
134190
invalidation by helping you to organize your caching and
135191
invalidation setup.
136192

137-
Varnish can be configured to accept a special HTTP ``PURGE`` method
138-
that will invalidate the cache for a given resource:
139-
140-
.. code-block:: varnish4
141-
142-
/*
143-
Connect to the backend server
144-
on the local machine on port 8080
145-
*/
146-
backend default {
147-
.host = "127.0.0.1";
148-
.port = "8080";
149-
}
150-
151-
sub vcl_recv {
152-
/*
153-
Varnish default behavior doesn't support PURGE.
154-
Match the PURGE request and immediately do a cache lookup,
155-
otherwise Varnish will directly pipe the request to the backend
156-
and bypass the cache
157-
*/
158-
if (req.request == "PURGE") {
159-
return(lookup);
160-
}
161-
}
162-
163-
sub vcl_hit {
164-
// Match PURGE request
165-
if (req.request == "PURGE") {
166-
// Force object expiration for Varnish < 3.0
167-
set obj.ttl = 0s;
168-
// Do an actual purge for Varnish >= 3.0
169-
// purge;
170-
error 200 "Purged";
171-
}
172-
}
173-
174-
sub vcl_miss {
175-
/*
176-
Match the PURGE request and
177-
indicate the request wasn't stored in cache.
178-
*/
179-
if (req.request == "PURGE") {
180-
error 404 "Not purged";
181-
}
182-
}
183-
184-
.. caution::
185-
186-
You must protect the ``PURGE`` HTTP method somehow to avoid random people
187-
purging your cached data. You can do this by setting up an access list:
188-
189-
.. code-block:: varnish4
190-
191-
/*
192-
Connect to the backend server
193-
on the local machine on port 8080
194-
*/
195-
backend default {
196-
.host = "127.0.0.1";
197-
.port = "8080";
198-
}
199-
200-
// ACL's can contain IP's, subnets and hostnames
201-
acl purge {
202-
"localhost";
203-
"192.168.55.0"/24;
204-
}
205-
206-
sub vcl_recv {
207-
// Match PURGE request to avoid cache bypassing
208-
if (req.request == "PURGE") {
209-
// Match client IP to the ACL
210-
if (!client.ip ~ purge) {
211-
// Deny access
212-
error 405 "Not allowed.";
213-
}
214-
// Perform a cache lookup
215-
return(lookup);
216-
}
217-
}
218-
219-
sub vcl_hit {
220-
// Match PURGE request
221-
if (req.request == "PURGE") {
222-
// Force object expiration for Varnish < 3.0
223-
set obj.ttl = 0s;
224-
// Do an actual purge for Varnish >= 3.0
225-
// purge;
226-
error 200 "Purged";
227-
}
228-
}
229-
230-
sub vcl_miss {
231-
// Match PURGE request
232-
if (req.request == "PURGE") {
233-
// Indicate that the object isn't stored in cache
234-
error 404 "Not purged";
235-
}
236-
}
237-
238-
.. _varnish-x-forwarded-headers:
239-
240-
Routing and X-FORWARDED Headers
241-
-------------------------------
242-
243-
To ensure that the Symfony Router generates URLs correctly with Varnish,
244-
proper ```X-Forwarded``` headers must be added so that Symfony is aware of
245-
the original port number of the request. Exactly how this is done depends
246-
on your setup. As a simple example, Varnish and your web server are on the
247-
same machine and that Varnish is listening on one port (e.g. 80) and Apache
248-
on another (e.g. 8080). In this situation, Varnish should add the ``X-Forwarded-Port``
249-
header so that the Symfony application knows that the original port number
250-
is 80 and not 8080.
251-
252-
If this header weren't set properly, Symfony may append ``8080`` when generating
253-
absolute URLs:
254-
255-
.. code-block:: varnish4
256-
257-
sub vcl_recv {
258-
if (req.http.X-Forwarded-Proto == "https" ) {
259-
set req.http.X-Forwarded-Port = "443";
260-
} else {
261-
set req.http.X-Forwarded-Port = "80";
262-
}
263-
}
264-
265-
.. note::
266-
267-
Remember to configure :ref:`framework.trusted_proxies <reference-framework-trusted-proxies>`
268-
in the Symfony configuration so that Varnish is seen as a trusted proxy
269-
and the ``X-Forwarded-`` headers are used.
193+
The documentation of the `FOSHttpCacheBundle`_ explains how to configure
194+
Varnish and other reverse proxies for cache invalidation.
270195

271196
.. _`Varnish`: https://www.varnish-cache.org
272197
.. _`Edge Architecture`: http://www.w3.org/TR/edge-arch

0 commit comments

Comments
 (0)