Skip to content

Instantly share code, notes, and snippets.

@cmalven
Last active August 12, 2020 22:59
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmalven/1a36d9062e9a8c733c1d to your computer and use it in GitHub Desktop.
Save cmalven/1a36d9062e9a8c733c1d to your computer and use it in GitHub Desktop.
Integrating Craft with Fastly

Running a Craft site on Fastly

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.

How Fastly Works

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.

Overview of steps involved

  1. Create a CNAME record pointing from your domain to global.prod.fastly.net
  2. Add a new service to Fastly for your site.
  3. Add a location declaration to your nginx or .htaccess so that all non-html static assets are served through the cache.
  4. Make sure gzip compression is being used in your nginx config or .htaccess (you should be doing this anyway).
  5. Add cache headers to your Craft templates.
  6. Add a rule to Fastly so that Craft's Set-Cookie header is removed.
  7. Add a rule to Fastly so that requests to URLs matching /admin are ignored and passed on to the origin server.

Step-by-step

Create a CNAME record pointing to Fastly

I'm going to assume you're using DNSimple. Instructions will be similar regardless of your DNS provider.

  1. While viewing your domain, click Add Record and choose CNAME
  2. For Name enter your domain name.
  3. Under Alias For enter global.prod.fastly.net
  4. Click Add Record

Add new Fastly service

  1. From within Fastly, click New Service.
  2. You can name the service anything, but choose something easily identifiable like my-website.
  3. The Origin Server Address will be the IP address of your server.
  4. The Domain Name will be the public-facing address for your site, such as my-site.com
  5. Click Create

Update nginx config

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

Add cache headers to Craft templates

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.

Tell Fastly to ignore Craft's Cookie Headers

By default, Craft http responses contain a Set-Cookie header which messes with Fastly. Fortunately, Fastly allows you to remove certain headers.

  1. While viewing your Fastly service, click Configure.
  2. Click Content from the sidebar navigation
  3. Next to Headers, click New
  4. 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.

  1. Click the Gear icon next to the header you just made, and choose Conditions
  2. 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.

Tell Fastly to ignore requests for the Craft admin section

  1. While viewing your Fastly service, click Configure.
  2. Click Settings from the sidebar navigation
  3. Next to Cache Settings, click New
  4. 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.

  1. Click the Gear icon next to the cache setting you just made, and choose Conditions
  2. 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.

Increase the Fastly First-Byte timeout

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 choose Advanced Configuration.
  • Increase the First Byte (ms) time to 30000
  • Click Update
  • Click Activate to deploy your changes.

Cache Busting

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:

  1. Manually purge caches through the Fastly admin when necessary.
  2. Use a Craft plugin that listens for changes to entries/assets and calls out to the Fastly API to purge its cache.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment