How to setup WordPress with AWS CloudFront CDN origin push

WordPress with CloudFront and S3

What is Amazon CloudFront CDN?

Amazon CloudFront is a fast content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally with low latency, high transfer speeds, all within a developer-friendly environment. CloudFront is integrated with AWS – both physical locations that are directly connected to the AWS global infrastructure, as well as other AWS services.

source: Amazon AWS

Why using origin push really matter?

Most Amazon CloudFront tutorials for WordPress I came across focus on setting up WordPress with pull origin which means CloudFront will first go to the original server (your server) to pull the requested file like an image, css or js file, CloudFront will cache the file at their edge servers until the file expires based on Default TTL (Time To Live) which is the default amount of time, in seconds, that you want objects to stay in CloudFront caches before CloudFront forwards another request to your origin.

Time To Live

This method of content delivery is great and easy to manage almost hands-free but can be slower than origin push and gives you no control over your files. Site visitors trying to access a file for the first time, or accessing it after the cache has expired, may notice a small lag while CloudFlare cache the file to their edge servers. Setting high TTL can help minimize the problem.

So what is CloudFront origin push and how to set it up?

Storing your site resources (images, CSS, Javascript) in Amazon S3 and using CloudFront to distribute it is considered origin push since your files are already stored inside Amazon AWS network, you only need to upload all your files to S3 once then use s3cmd to sync new files from your server to S3. Origin push gives you greater flexibility and control over your contents and save on bandwidth usage as well.

Here’s the deal:

I will describe 2 methods to accomplish this and both require caching plugin like W3 Total Cache (Freemium) or WP-Rocket (Paid). Both are great plugins but I will use WP-Rocket here for its ease of use.

Method 1 (Preferred): Using s3cmd

Step 1- Login to your AWS account and create a new S3 bucket in AWS and let’s call it www.domain.com for uniqueness, this will serve as your files repository

Step 2- Install and configure s3cmd to upload your files to your S3 bucket, for servers running CentOS7 or a RHEL7 variation as root run:

# yum install s3cmd
# s3cmd --configure

for servers running Debian or Ubuntu run this command:

$sudo apt-get update && sudo apt-get install s3cmd
$sudo s3cmd --configure

You’ll be prompted for AWS access_key and access token with Read/Write access to your S3 bucket and Encryption password, you can use password you like.

If s3cmd is not available in your OS package repo you can add s3tools repo by following instructions at s3tools.org website.

Step 3- Copy your wp-content folder to S3 bucket using this command:

# s3cmd put -r --add-header=Cache-Control:max-age=31536000 /home/username/public_html/wp-content s3://www.domain.com/

# s3cmd put -r --add-header=Cache-Control:max-age=31536000 /home/username/public_html/wp-includes s3://www.domain.com/

> Choose max-age as desired 31536000 = 1 Year

Step 4- Create a cronjob to sync new files to S3 every 5 minutes automatically:

*/5 * * * * root /usr/bin/s3cmd sync -r –delete-removed –add-header “Cache-Control:max-age=31536000” /home/username/public_html/wp-content/ s3://www.domain.com/wp-content/

*/5 * * * * root /usr/bin/s3cmd put -r —delete-removed –add-header “Cache-Control:max-age=31536000” /home/username/public_html/wp-includes/ s3://www.domain.com/wp-includes/

Step 5- Now switch to CloudFront and create a new Web distribution as shown:

Amazon aws cloudfront behavior settings

Step 6- Select your Amazon S3 bucket from (Origin Domain Name) field drop down, and if your site use HTTPS protocol – most website should for security, privacy and SEO – select (Redirect HTTP to HTTPS). If you have your own wildcard SSL Certificate you can upload it through Amazon AWS certificate manager , select (Custom Certification) and use your certificate for serving your site resources. You can also request a wildcard certificate issued by Amazon for free from AWS certificate manager and use that instead, (Allowed HTTP Methods) then accept all default and click Create Distribution. You can go back after creating the distribution to modify your configuration.

aws cloudfront distribution settings

7- Create a CNAME for your distribution domain name for example (a1b2c3d4e5f6.cloudfront.net), create a new record with the following values:

Name: cdn.domain.com
Type: CNAME
Value: a1b2c3d4e5f6.cloudfront.net

Step 8- Install and activate WP-Rocket (v2.9.11 as of this writing)

WP-Rocket CDN

Step 9- Open the CDN tab and check the option to (Enable Content Delivery Network)

Step 10- Replace site’s hostname with: https://cdn.domain.com

Step 11- Save Changes

Step 12- When adding new files to S3 wait 5 minutes for CloudFlare to distribute your files to edge servers.

 

Method 2: Using AWS and WP Offload Media

Install Amazon Web Services and WP Offload Media plugins by following this video:

 

 

 

 

Use the method that makes more sense to you but remember using CDN is better than not using one at all. CND means better site performance and improved search engine ranking.

I hope you find this tutorial useful and if I missed any step feel free to add it in the comment below.

The best part?

If you have a cPanel or Plesk VPS server with us contact support to install s3cmd and create the cronjobs for you. If you looking for a new VPS to host your WordPress site contact us today to get started.

 

Get started with Premium VPS hosting for WordPress today

8 thoughts on “How to setup WordPress with AWS CloudFront CDN origin push”

  1. This is not server push, in push, your initial response headers from CloudFront should include links to resources which will be contained in the body of the response, like links to your assets. You’ve enabled basic HTTP2 support, while still better than the older alternative, is not “push” like your article title suggests.

    It’s worth reading this: https://www.smashingmagazine.com/2017/04/guide-http2-server-push/

  2. JP, I think you’re confusing between CDN push as described in this article and HTTP/2 server push. Both solve 2 different problems. HTTP/2 server push has to do with preloading site assets for browser to cache and to reduce the number of requests. CDN origin push is primarily used to upload website assets to CDN servers (S3 in this case, then distribute the assets to Amazon CloudFront edge servers) as opposed to CDN servers PULLing site assets to edge servers. Enabling HTTP/2 here is optional and is not the focus of this article, but i’m glad you brought it up so others can benefit from implementing HTTP/2 support in their CloudFront distribution.

  3. Hey,

    Does this command- s3cmd put -r –add-header=Cache-Control:max-age=31536000 /home/username/public_html/wp-content s3://www.domain.com/ recursively iterate through files and uploads them or just uploads them no creating sub-folder under folders.
    Also I have multiple files to upload so how do i setup mime-type for different files.

    Appreciate your help!!

  4. Yes, but this is the command you should use:
    s3cmd sync -r –delete-removed –add-header “Cache-Control:max-age=31536000” /home/username/public_html/wp-content/ s3://www.domain.com/wp-content/

    Using s3cmd with (sync) and (-r) options will recursively sync the entire folder, subfolders and files, (-delete-removed) option will delete all files from s3 that don’t exist on your server.

    To setup mime-type for different files you should group similar files together in a folder and create a separate cron for this folder with –mime-type=MIME/TYPE option, if that’s not possible create a cron for each file with different mime-type and schedule it to run after the parent folder sync.

    A full list of s3cmd command options is available here > http://s3tools.org/usage

  5. Great tutorial. Very helpful!

    Any help with finding a way to exclude a specific subfolder from inside of /home/username/public_html/wp-content/uploads/ would be awesome. I have a folder /home/username/public_html/wp-content/uploads/backupbuddy_backups/ which I don’t want to have synced to S3

    I looked at the docs at S3cmd but have not had much luck in figuring out to exclude a subfolder. This is the command I created that is NOT working

    /usr/bin/s3cmd sync -r –exclude “home/USERNAME/public_html/wp-content/uploads/backupbuddy_backups/*” –delete-removed –add-header “Cache-Control:max-age=31536000” /home/USERNAME/public_html/wp-content/ s3://www.mydomainBucketName.com/wp-content/

    I also tried:

    /usr/bin/s3cmd sync -r –exclude “/home/USERNAME/public_html/wp-content/uploads/backupbuddy_backups/*” –delete-removed –add-header “Cache-Control:max-age=31536000” /home/USERNAME/public_html/wp-content/ s3://www.mydomainBucketName.com/wp-content/

    Note the small change of adding a / before home in the exclude flag –exclude “/home

  6. Per S3cmd usage page, exclude option has double dash and followed by equal sign as in –exclude=
    I would also try the directory path without asterisk. so the command should look like this:

    /usr/bin/s3cmd sync -r –exclude=”/home/USERNAME/public_html/wp-content/uploads/backupbuddy_backups” –delete-removed –add-header “Cache-Control:max-age=31536000” /home/USERNAME/public_html/wp-content/ s3://www.mydomainBucketName.com/wp-content/

  7. Hi,

    Nice article, thanks ! That being said, in the case of WP Rocket, I struggle with minified / combined css (and others) and CDN integration.

    In pull mode, it seems that the minified/combined version is not uploaded.

    In push mode, how do you manage to push this version and not the standard js/css ?

    Benoit

  8. I haven’t used pull mode with AWS so i can’t comment on that, your best bet is to contact WP Rocket support.

    For push mode, you’re pushing wp-content folder which has the cache folder where wp rocket store minified js & css files (reserved for: All files option must be selected in this case), however i only push images because i found js minification to be problematic and the option to add a separate CNAME for css was not available in the version i used but in the current version you can add a separate CNAME for css or js.

Leave a Reply

Your email address will not be published. Required fields are marked *

Top