Easy Drupal CDN integration for fun and profit
Speed up your Drupal site with a CDN in a few minutes.
The fun part: it’s nice to learn how to make any Drupal site significantly faster in a few minutes.
The profit part: faster websites lead to more users and more revenue.
This article covers the common case: you have a small to medium size (≤1M page views per month), without massive amounts of large images, you’re using Drupal 71 and you only want to spend a few euros or (U.S.) dollars per month on a CDN. (You already know what a CDN is, right?)
So, you want your Drupal site to be faster, only spend a few minutes doing so, don’t want to deal with infrastructure and want to keep the costs very minimal. You’ve come to the right place.
Also: don’t worry about the cost: this little experiment will only cost you a few cents.
We’ll be using Amazon CloudFront and my CDN module for Drupal — I hope you like it. I’ve tried to make it as easy to use as possible. It’s solid, it’s got unit tests where appropriate, it’s used by ±2,000 Drupal sites — http://economist.com and http://worldpressphoto.org amongst others.
My largest deployment is for http://driverpacks.net, where the total CDN bill for well over half a million page views per month is less than USD $10!
Part 1: Create an Amazon CloudFront Distribution with a Custom Origin
We’ll be using Amazon’s CloudFront CDN service. Why?
They’re reliable, have solid performance (though not the best), are affordable (though not the cheapest) and are continuously expanding (i.e. adding more Points of Presence) around the globe. In just the last six months, they added five new edge locations2. So your site will automatically get faster in more locations around the globe, without paying more. Also see their list of edge locations or their map. Amazon is also cutting prices regularly (July 2011 was the last time). You’ll generally also never run into problems — after all, there are bigger fishes out there that help drive the infrastructure forward, you can just get an easy ride along.
You are of course free to use a different CDN, but then you’ll have to make sure you’re using an Origin Pull CDN.
So, go to https://aws.amazon.com/ and sign up for an account if you haven’t already. Go to the AWS Management Console and sign in. Go the CloudFront tab and click the “Create Distribution” in the top left corner.
Amazon recently updated their management console, and now (January 5, 2013) the steps below are outdated:
A wizard modal window will pop up (on the first page of the wizard: “Distribution Type”), where you can choose between two types of origins3: Amazon S3 Origin and Custom Origin. Choose Custom Origin; this means Amazon CloudFront’s edge location servers will come to your Drupal site’s web server and retrieve the files it needs to serve to end users. You won’t have to deal with Amazon S3 at all.
In the Origin DNS Name field, enter the domain name of your Drupal site: www.yoursite.com
. In my case, I entered wimleers.com
(my site is accessible both with and without the www
). Next: the Protocol Policy field. If your site is only accessible via HTTP and not via HTTPs, then just go with the default HTTP Only option. If your site supports https
(or you want to support this in the future), then select Match Viewer. Finally, click “Continue”.
Now you’re on the second page of the wizard (“Distribution Details”). You don’t need to change anything here. Click “Continue” again. We’re now on the “Review” page of the wizard. Click “Create Distribution”. You should get a message stating “You have successfully created a CloudFront Distribution.” Great!
The new steps are:
A 2-step wizard will appear. In the first step, you must select the delivery method: “Download” or “Streaming”. Choose “Download” (the default) and click “Continue”. In the second step, there are three groups of settings: “Origin Settings”, “Default Cache Behavior Settings” and “Distribution Settings”. We only care about the first group of settings, the others we can leave at the default (though you may want to change the “Price Class” setting in “Distribution Settings” to indicate that you only want to use U.S.& European edge locations, for example). So, “Origin Settings”: for “Origin Domain Name”, enter the domain name of your Drupal site: www.yoursite.com
. In my case, I entered wimleers.com
(my site is accessible both with and without the www
). Now three additional settings will appear (because you’re using a custom origin and not Amazon S3): “Origin Protocol Policy”, “HTTP Port” and “HTTPS Port”. All of them have sane defaults. Only the “Origin Protocol Policy” setting (defaulted to HTTP Only, changeable to Match Viewer) is somewhat likely to be relevant to you. if your site is only accessible via HTTP and not via HTTPs, then just go with the default HTTP Only option. If your site supports https
(or you want to support this in the future), then select Match Viewer. Finally, click “Continue”.
At the top of your CloudFront Management Console’s table of distributions, you should now see something like this:
Your newly created distribution’s status will remain at InProgress for a few more minutes, then it will change to Deployed. As soon as it is Deployed, we can actually use it.
If you have more special needs, consult Amazon’s documentation on creating distributions. More often than not, you won’t need that though.
Part 2: integrate your Drupal site with the CDN!
Download the CDN module for Drupal (version 2.5 or later). Install it like you install any other module. After the installation, go to admin/config/development/cdn
(admin/settings/cdn
on Drupal 6). There’s three tabs:
- General
- Details
- Other
We’ll cover them one by one. Note that you can install the Advanced Help module to get more and better help (it’ll help you explore all features of the CDN module).
First tab: “General”
There’s really only one important setting here: the status of the CDN module. You can either disable it, enable it, or put it in testing mode, which is somewhere in between. In testing mode, none of your visitors will get files from the CDN; only users with the access files on CDN when in testing mode permission will get to see it. This is perfect to test whether the CDN integration is actually working correctly. So, for now, let’s put it in testing mode.
The second (and last) setting on this tab is the Display statistics setting. Users with the access per-page statistics permission will get to see, well, per-page statistics at the bottom of each page: “what percentage of files is served from a CDN”, and so on. Enable this for now, so you get to see the results for each page on your site.
Second tab: “Details”
At the top of this tab, there’s a Mode setting, which allows you to choose between Origin Pull and File Conveyor. Choose Origin Pull (the default).
Next, there are mode-specific settings. The most important one is the “CDN mapping” setting. Here we define which files are mapped to which CDN (in case you’re using multiple CDNs — or static file servers).
Go back to the CloudFront Management Console and copy the domain name of your CloudFront Distribution. In my case: d67something714.cloudfront.net
. Now paste this into the “CDN mapping” setting, but prepend it with http://
. So your CDN mapping is now set to http://d67something714.cloudfront.net
. This will cause all files to be served from CloudFront.
Read the included Advanced Help documentation to see what else is possible (e.g. serve images from a different CDN or only serve CSS and JS from a CDN), but for us (and for http://wimleers.com), this CDN mapping will do.
Optional, but recommended: Far Future expiration
The last setting on the “Details” tab is the Far Future expiration checkbox. This single checkbox has the capability to make your site much faster than when you were just using a CDN without this setting enabled. It can also reduce your CDN bill significantly.
What does it do? Well, it ensures that all files are served from the CDN in the most optimal way possible: compressed (gzipped) whenever possible and with the most optimal HTTP headers. These HTTP headers tell your visitors’ browsers to cache files “forever”. The results: less requests to the CDN (reducing your bill), and hence an even faster site! Whenever the file changes, its URL is changed automatically, so that your visitors don’t continue using that old buggy JS or CSS file forever, but they get the new files immediately.
There’s a catch though: to be able to set these HTTP headers and automatically4 change file URLs to be unique, we have to serve the files through PHP (Drupal) instead of letting the web server take care of it… This has adverse performance effects: using PHP to serve static files is not efficient!However, the CDN caches these files for long periods of time (CloudFront edge locations come back to the origin once every 24 hours, no matter what expiration date you configure), so in fact that’s just fine. Hence you should only enable this setting if you’re using a CDN or a reverse proxy such as Varnish. It won’t work when you’re using “your own CDN”, i.e. just a static file server such as nginx or lighttpd. It will work when you’re using the same web server for these alternative domains as you’re using for serving the actual Drupal site, but in that case, very long load times are the result.
Again: no worries, the CDN module checks this automatically for you. After you submit the “Details” form, you should see a status message that confirms everything is a-ok:
Once you’ve enabled the Far Future expiration setting, a new setting appears: Unique file identifier generation. This defines how each file’s unique file identifiers are generated. The default works fine for all sites, but for complex and/or high-traffic sites, you may want to fine-tune this.
Third tab: “Other”
We won’t go into the details of the various settings on this tab, but there’s only one we care about for the scope of this article: the CDN supports HTTPS setting. If your site is using HTTPS and you configured your CloudFront distribution’s Protocol Policy to Match Viewer, then you can enable this setting as well. Whenever your site is accessed through HTTPS, your files will still be served from the CDN, via HTTPS!
All done!
If you haven’t already, make sure you’ve enabled Drupal’s CSS aggregation, block caching and page caching. The CDN module automatically rewrites image URLs in blocks and nodes, but we don’t want that to happen on every page load if it’s not necessary — hence enable those caching layers.
By now, the status of your CloudFront distribution should have changed to “Deployed”. So let’s give this a try! The following screenshot was taken at http://wimleers.com/blog/facebook-week-12:
If everything is looking good after browsing through your website and confirming that the CDN integration is working correctly everywhere, head back to the “General” tab and change the status from Testing mode to Enabled. Now your site’s actual visitors will also get all files served from the CDN, so they should be experiencing a faster site! Definitely return visits should be significantly faster. Your status report should look similar to this:
Congratulations, your site is now accelerated by a CDN!
-
This will work for Drupal 6, too. ↩
-
October 2011: Sao Paulo, Brazil. December 2011: South Bend, Indiana, U.S.A; San Jose, California, U.S.A.; second edge location in New York City, New York, U.S.A. February 2012: Osaka, Japan; Milan Italy. ↩
-
The “origin” defines what the “origin server” is, i.e. where CloudFront edge location servers around the world will go to get the files they need to serve to your site’s visitors.
Also see “The Origin Server” in Amazon’s documentation. ↩ -
“Automatically” as in “out of the box”; without modifying Apache’s
.htaccess
orhttpd.conf
files and similar web server config files for other web server software. ↩