How to set up a CDN (Amazon CloudFront) in Magento
If you are using Amazon AWS CloudFront and you want to set up CDN in your Magento, this tutorial is going to take you step by step on how to set up your CloudFront and Magento to get it both working.
STEP 1 – DISTRIBUTIONS
The first thing you have to do is to set up Distribution on CloudFront. Below you can see an example of my custom Distribution.
This is how general options should look like, of course you can edit them to suit your needs.
As you may see here:
Amazon’s CloudFront uses its own certificate so if your site uses SSL you can just use CloudFronts’s domain name such as “https://xyz13zxy.cloudfront.net”. You can also use custom CDN url with SSL such as “https://cdn.yoursite.com” but then you’ll have to import your own certificate.
Two very important options you need to be careful about are:
Alternate Domain Names (CNAMEs): this is used if you want nicer URLs for your content. So for example, if your CNAME is “cdn.yoursite.com” you will have to do some configuration in your cPanel of your own server to make it work and instead of, for example “http://www.yoursite.com/images/image.jpg” it’s going to be “http://cdn.yoursite.com/images/image.jpg”
Domain Name: This is a domain name Amazon generates for you, for example: “xyz13zxy.cloudfront.net”. If you don’t care about URL for your CDN this is faster and easier way to set up CDN. So instead of, for example “http://www.yoursite.com/images/image.jpg” it’s going to be “http://xyz13zxy.cloudfront.net/images/image.jpg”.
So how Amazon knows which images to use if you are trying to access it via “xyz13zxy.cloudfront.net”. This is where the Origins come in.
STEP 2 – ORIGINS
Now you have to set Origins. Amazon’s official documentation says: “When you create or update a distribution, you provide information about one or more locations—known as origins—where you store the original versions of your web content. CloudFront gets your web content from your origins and serves it to viewers. Each origin is either an Amazon S3 bucket or an HTTP server, for example, a web server”.
Origin Domain Name: this is your source domain name, for example “www.yoursite.com”
Origin ID: this is some ID you specify by yourself just to easily identify this Origin. It can be something similar to your CDN domain name.
Origin Path: it’s empty. Amazon’s official documentation says: “Optional. If you want CloudFront to request your content from a directory in your Amazon S3 bucket or your custom origin, enter the directory name here, beginning with a /. CloudFront appends the directory name to the value of Origin Domain Name when forwarding the request to your origin, for example, myawsbucket/production.”
STEP 3 – BEHAVIOURS
The next thing you have to do is to set Behaviours. Amazon’s official documentation says: “A cache behaviour lets you configure a variety of CloudFront functionality for a given URL path pattern for files on your website. For example, one cache behaviour might apply to all .jpg files in the images directory on a web server that you’re using as an origin server for CloudFront. ”
When using CDN sometimes you might get an error on your website similar to this one: “Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://xyz123zxy.cloudfront.net/images/images.jpg This can be fixed by moving the resource to the same domain or enabling CORS.”
To fix this problem you have to set Behaviours.
Origin: It’s very important to choose the right Origin from the dropdown box. This is your Origin you set up in the previous step.
Whitelist Headers: choose “Origin” from the left box and click on Add >>. When you choose your other options click on Create/Edit.
Path Pattern: This is path to a file you want to allow CORS for. I’m using “*” so it matches all files and allows Cross-origin resource sharing.
STEP 4 – INVALIDATIONS
You might be wondering how and when the cache is going to be invalidated or cached again. By default, each object automatically expires after 24 hours.
From Amazon’s official documentation: “To change the cache duration for all objects that match the same path pattern, you can change the CloudFront settings for Minimum TTL, Maximum TTL, and Default TTL for a cache behaviour. For information about the individual settings, see Minimum TTL, Maximum TTL, and Default TTL. To use these settings, you must choose the Customize option for the Object Caching setting.”
If you want to invalidate cache for all files (which is not recommended) or just for one specific file, you have to set “Invalidations”.
Enter path to your own files and click on Invalidate.
STEP 5 – MAGENTO SETTINGS
This was CloudFront’s side, now it’s time to configure Magento’s settings. It’s really easy to configure Magento. The only thing you have to do is to configure Magento’s URLs. Screenshots below are using SSL (HTTPS) so I used “https://…” everywhere. If you don’t use SSL, but regular HTTP, then you should use ”http://…”.
As you may see, nothing has changed in Default settings.
Choose your Website from the dropdown and change only fields where you want to set CDN URL. I chose to set CDN only for images and CSS files.
Save your settings, clear your cache and test your website. How do you know if your site uses CDN now? Open your website (if you are using Chrome) and press CTRL and U on your keyboard to open the source code. If you can find something like “.cloudfront.net” or “cdn.yoursite.com” and all your content is loading properly that means CDN is set up properly.
It’s very helpful article on buy managed aws server
I have followed all these steps but it didn’t work. The all the media files is not getting upload to s3 bucket.
The distribution link is shown in the website but the images is not showing , getting an error I.e no such key.the specified key is not exist.
Please help me out. I am getting stuck
There is small problem as i setup everything and working almost except cache issue for product images.
As i am using S3 bucket and S3FS-FUSE for syncing my /media folder with S3 bucket with rsync (cronjob).
As rsync is very slow in syncing cached images with S3, thus it results in broken image links on main product pages as cached images are not present in S3.
This is actually a known problem with the CDN, i am also not able to figure out any workout.
Is it possible to modify some code in magento 184.108.40.206 for MAIN PRODUCT IMAGE, that magento will load only original images from CDN S3, not the cached images.
How can I exclude JS files from cloudfront when they are being merged and located under media/js ?
Thanks for you tutorial!
Can you guide me how can I setup cdn for my staging site on subdomain?
What settings should I made in amazon cdn console and admin magento?
Thanks for your guide!
I want to know how can I setup this for my staging site with subdomain?
I have made all changes. Admin is working fine but in front css/js files are not loading.
What should I make settings in Amazon CloudFront and my magento admin to make it working with subdomain.
Thanks in advanced!
Really very helpful article I have setup my magento site.
My problem is that I upload all my products using the import function on Magento, it is easier to upload products in bulk using a CSV file in this way.
I have a field for images, and I upload all my images first on S3 bucket which I have set my origin in Cloudfront to fetch these images. So everything is setup fine regarding displaying the images on CloudFront if I add the absolute URL of the image path in the browser my image shows fine, so this is the image URL I add to my CSV file for Magento to find and upload my images according to each product.
So once I upload my products via a CSV file Magento fetches my images from S3 bucket and adds them to Magento folders. Now I have uploaded my images but they not showing from CloudFront rather from the same server as Magento. The next step I create the same folder structure as Magento for my images and CSS files and upload all the images and files to S3 bucket. Then I go to Magento backend and change the Base Site/Media URL to CloudFront, this now fetches my images and files from Cloudfront.
Now my file name for the images once fetched has the CloudFront URL I added in my backend and adds the absolute URL also as a filename from my CSV file I added, so the filename is terribly long and looks cumbersome.
Also now I have a duplication of images on my Magento server and S3 and every time I want to upload more images I have to copy all the folders and files from Magento server to S3, this is a long tedious process.
Please advice what I am doing wrong and if there is a way I can do this better and more efficient?
Hello Dario Trbovic
Thank you so much for for your tutorial. Could you make tutorial about Amazon Route 53?
And how to set up a Amazon Route 53 in Magento.
I’ve never worked with it before, but if I ever encounter it in my development process I’ll write tutorial about it 🙂
Thanks for this great tutorial, helped me a lot!
I’m glad 🙂
Thanks Dario Trbovic for this tutorial it is very helpful for me.
No problem, my pleasure :=)
If you hosted an online store that only delivered to your country (UK for example), then simply having a London based Web Server would suffice. Obviously, you would get a slight benefit from a lighter load from the server depending on what you were hosting, but that’s probably negligible unless you’re getting 1,000s of visits per day.
However, if you’re serving an international audience or getting the hits then a CDN is definitely a recommendation.
Thanks for the how-to!
That’s exactly right. No problem 🙂
Any speed results/tests on this, did it actually improve performance in real life situations?
I didn’t do any tests, but the good things is that Amazon has servers all over the world, so if you are from US the content will be delivered from server closer to you in US and response time will be lower (https://www.google.com/maps/d/u/0/viewer?mid=1o5Fwi6FLht7HklJWSy4LA0yHnjo&hl=en&ll=24.190524153358062%2C8.679816499999959&z=2)
And of course you don’t waste bandwidth on your hosting, you are paying bandwidth for static content to Amazon so you can use bandwidth on your server for more important stuff