In this post I will cover a simple way to configure Magento to use the Amazon CloudFront CDN service and to create a CloudFront distrubution that mirrors the static files in your site. This method relies on the custom origin functionality announced late last year when CloudFront came out of beta. But first, a little background.
A CDN (content distribution network) is a network of servers that puts your files and content closer to the user requesting them, and thus they can get the quicker. Using a CDN has a nice side effect of offloading some work from your own server too – which if you use Apache means less processes on your server for each customer.
When Amazon first announced CloudFront I got very excited about the prospect of writing an extension to automatically sync a Magento store’s media with an S3 bucket, to enable this simple, affordable CDN solution. Alas, it turned out to be quite hairy dealing with the subtle race conditions that can occur when first accessing a specific media file that may not be available on the CDN yet.
With the introduction of custom origin functionality there is no situation where the CDN won’t have the file. If the CDN doesn’t have the file, it gets it from the underlying source server, if it already has it, it serves it. This means the first request for a file will be a bit slower, but after that it’ll be quick.
So to make a CloudFront distribution work in Magento it only takes two steps.
Step 1: Create the CloudFront distribution
You can do this on the command line with the aws tools, or through the Amazon AWS console. Let’s take pictures of the console, it’s getting late.
The dialog box that pops up will guide you through the creation process. There’s not much to it.
Specify a custom origin and then enter the current domain name of your site as the origin. The option to match the viewer is not required, it makes little difference either way as far as I’m aware.
In the next step you will probably want HTTPS and HTTP, and it’s a chance to add the CNAME in advance (if you think you want a CNAME, read the next section first). If you’re unsure don’t worry you can edit it later.
Review your configuration and save the distribution, it can take 10 minutes or so to become available, you can test it by going to the url for your store logo (something) like this
http://d56xhwfHe9rhq4.cloudfront.net/skin/frontend/package/theme/images/logo.gif. You should see your logo.
Step 2: Configure Magento to use it
Base url’s can be a major pain in modern web apps, but Magento has a pretty solid framework for them that makes adding a CDN very easy.
System -> Configuration -> Web and specify your distribution URL from step 1 as the Base Skin URL and Base Media URL in the Unsecure section.
The URL’s for skin and media should look something like this, don’t forget the trailing slash:
Note: You can add this in the Secure section too if you want to, just make sure you specified HTTPS in your CloudFront distribution when you created it. Also cloudfront doesn’t do custom SSL certificates, so if you do the CNAME step below, you won’t also be able to do HTTPS connections with it. I’m sure Amazon’ll be working on this, they have it for the elastic load balancer already.
Extra for experts: CNAME the distribution
So the only bummer about what we have so far is the name of the server the files are coming from, it looks a bit dumb if the user sees it in the browser status bar, or looks at the source. We can mask it with a CNAME, for example we can map content.yourdomain.com to the CloudFront distribution you created. I won’t cover creating a CNAME here, it’s well documented in a number of places and your host or domain registrar will be able to point you to a suitable guide.
Once you have the CNAME setup and it has propgated around the internet, you can safely update the base url’s in your Magento configuration to point to your nice tidy CNAME domain, like content.yourdomain.com. Only put them in the Unsecure section though, as Cloudfront cannot serve HTTPS content from custom CNAME’s yet.
What about updating the files when they change?
Good question! Files will expire from the network based on the expiry specified when they were retrieved. I’m assuming in a production webstore these things won’t be changing too often, a CDN setup wouldn’t be good for a store whose product images or logo change frequently for example.
If you really need a file to change quickly then you can either revert to not using the CDN (i.e undo step 2 above) or you can issue an invalidation request. This doesn’t have a UI yet, so to do it you need to be comfortable with some scripting. Issuing an invalidation request for all files in a particular theme, or all media files from the Magento admin would be a simple but quite useful extension, I think.
So that’s it, putting your Magento static files onto a enterprise quality CDN like CloudFront is easy and fun!