Fastly is essentially Varnish as a service. Similarly to how Heroku drastically simplifies the running of a web server, Fastly simplifies full-page caching of websites with running with dynamic content.
In a nutshell:
- Every time there is a request for your website, it is routed through Fastly instead of directly to your backend.
- If Fastly has an existing cache for the requested URL, it serves the cached page and your backend isn't touched at all.
- If Fastly doesn't have an existing cache for the URL, the request will hit your backend as it normally would and Fastly will cache the page.
- Increase the Fastly First-Byte timeout limit so that Craft's Auto-Update continues to work.
The net result is that the pages of your site are served as if they were static files, so the time to deliver the page is drastically reduced.
- Create a CNAME record pointing from your domain to
global.prod.fastly.net
- Add a new service to Fastly for your site.
- Add a
location
declaration to your nginx or .htaccess so that all non-html static assets are served through the cache. - Make sure gzip compression is being used in your nginx config or .htaccess (you should be doing this anyway).
- Add cache headers to your Craft templates.
- Add a rule to Fastly so that Craft's
Set-Cookie
header is removed. - Add a rule to Fastly so that requests to URLs matching
/admin
are ignored and passed on to the origin server.
I'm going to assume you're using DNSimple. Instructions will be similar regardless of your DNS provider.
- While viewing your domain, click
Add Record
and chooseCNAME
- For
Name
enter your domain name. - Under
Alias For
enterglobal.prod.fastly.net
- Click
Add Record
- From within Fastly, click
New Service
. - You can name the service anything, but choose something easily identifiable like
my-website
. - The
Origin Server Address
will be the IP address of your server. - The
Domain Name
will be the public-facing address for your site, such asmy-site.com
- Click
Create
Apache (.htaccess) will require different steps than outlined here, but will be similar.
- In your nginx config, add the following to cache static assets:
location ~ ^(?!(/admin/))(.*)\.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1h;
}
- In the same config file, add the following to enable gzip compression:
# enable gzip compression
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain application/x-javascript image/svg+xml text/xml text/css;
gzip_vary on;
# end gzip configuration
If your Craft pages use a shared _layout
template, add the following to the top of that file:
{% set expiry = now|date_modify('+30 days') %}
{% header "Cache-Control: max-age=" ~ expiry.timestamp %}
{% header "Pragma: cache" %}
{% header "Expires: " ~ expiry|date('D, d M Y H:i:s', 'GMT') ~ " GMT" %}
If you don't have a shared _layout
, add the above to the index template for any page you want Fastly to cache.
By default, Craft http responses contain a Set-Cookie
header which messes with Fastly. Fortunately, Fastly allows you to remove certain headers.
- While viewing your Fastly service, click
Configure
. - Click
Content
from the sidebar navigation - Next to
Headers
, clickNew
- Add the following settings, then click
Update
.
Name: Remove Craft Cookie Header
Type / Action: Cache / Delete
Destination: http.Set-Cookie
Ignore if Set: No
Priority: 10
Then we need to add the condtions that will trigger this.
- Click the Gear icon next to the header you just made, and choose
Conditions
- Set the following, then click
Update
Name: Not Admin
Apply If... !req.url ~ "/admin"
Priority: 10
Then you'll have to click Activate
at the top of the Fastly view to make your changes active.
- While viewing your Fastly service, click
Configure
. - Click
Settings
from the sidebar navigation - Next to
Cache Settings
, clickNew
- Add the following settings, then click
Create
.
Name: Force Pass on Admin
TTL: 0
Stale TTL: 0
Action: Pass
Then we need to add the condtions that will trigger this.
- Click the Gear icon next to the cache setting you just made, and choose
Conditions
- Set the following, then click
Update
Name: Admin
Apply If... req.url ~ "/admin"
Priority: 10
Then you'll have to click Activate
at the top of the Fastly view to make your changes active.
Craft's auto-updating can take awhile, so we need to make sure Fastly gives it time to finish before timing out.
- In your Fastly service, click
Configure
- Click
Hosts
from the sidebar - Under
Backends
, you should see one item. Click the gear icon next to it, and chooseAdvanced Configuration
. - Increase the
First Byte (ms)
time to 30000 - Click
Update
- Click
Activate
to deploy your changes.
The only downside to a Fastly/Craft integration is that Fastly has no way of knowing when changes are made through Craft, so it will continue to serve stale content unless you inform it to bust its caches.
There are a few ways to address this, none of which are perfect solutions at the moment:
- Manually purge caches through the Fastly admin when necessary.
- Use a Craft plugin that listens for changes to entries/assets and calls out to the Fastly API to purge its cache.