Archived post from 2014. Kept for reference; the technology is outdated.

Configure subdomain as “CDN” in NGINX (+ WordPress & W3 Total Cache configuration)

4 min read

UPDATE: CORS (Cross-origin resource sharing) added to the “fake” CDN. Based on: https://gist.github.com/alexjs/4165271

In a typical scenario, you serve your webpage from a single domain, which includes all your “server generated” pages and also the images and assets (JavaScript, CSS and other files) of your site.

This can slow down your page speed. Most of the browsers create maximum two/four simultaneous connections when downloading a page from the web server, so other connections have to wait. There is also another problem, your domain could serve some cookies with your assets, which can decrease also the page performance.

The best solution for this problem is to invest in a real CDN (Content Delivery Network). CDNs are optimised to serve images and assets (without cookies), they have their own domains, release the load of your server and they are distributed in multiple data centres (so your users are going to download the assets faster because they are near them).

The problem: CDNs cost you money.

If you can afford it, go and take one (your page will load faster). If not, you can have some of the benefits of having a CDN, configuring a subdomain to serve this content. This is not a real CDN because it’s not a “Network” (Data is not distributed in multiple data centres) and your server has to load and serve the assets, but you can benefit from more simultaneous connections and get rid of the cookies. You can see an example on this page 🙂

As I’m using NGINX as a web server, I’m going to show you how to configure in it a “fake cdn” subdomain.

First you have to create a new subdomain/server configuration in “/etc/nginx/sites-available” with this content:

 1server {
 2    listen   80; ## listen for ipv4
 3    listen   [::]:80; ## listen for ipv6
 4    server_name cdn.yourdomain.com;
 5    access_log /var/log/nginx/cdn.yourdomain.com.access.log;
 6    error_log  /var/log/nginx/cdn.yourdomain.com.error.log;
 7
 8    root /var/www/your/web/folder/;
 9    
10    include sites-available/cdn.conf;
11}

You have two options:

– use the same content folder of your current installation/web page (I recommend this if you are doing this with WordPress or if you don’t want to move or copy your files from one folder to another). In this case the line “root /var/www/your/web/folder/;” has to point to your current web folder or WordPress installation.

– configure a new empty folder (change the line according to the “root /var/www/your/web/folder/;”) and move there your assets.

As you can see there is an include (“include sites-available/cdn.conf;”) I’m going to show you the content of the cdn.conf file (it has some additions for WordPress installations):

Change the line 7 to redirect your users to an error page or create the 404.html page in your web folder.

The file is commented, if you want to know more. The configuration includes some advantages, such as:

– No php execution in the subdomain.

– Set maximum browser cache for images, CSS and other static files.

– Don’t send cookies in the subdomain.

Now, you have to make a symbolic link of the first file that you have created into “/etc/nginx/sites-enabled” and restart NGINX.

Your subdomain must be working now. If you have chosen the first option (use the same content folder of your current installation/web page) you can access the same files through your new subdomain. For example, on my server:

http://jesus.perezpaz.es/wp-content/uploads/2013/03/mc-1-280×300.jpg -> http://cdn-jesus.perezpaz.es/wp-content/uploads/2013/03/mc-1-280×300.jpg

It’s the same image but one is served with the default server configuration and the other one with all the improvements of the new subdomain.

If you have chosen the second option you can upload your assets to the new folder and see the subdomain working.

More generic optimisations could be done in your NGINX configuration. You can search the internet for those, there are plenty of sites with this information 🙂

WordPress & W3 Total Cache configuration

So, you have now your new “CDN” running and you want to use it in WordPress… easy 🙂

I’m going to use the plugin W3 total cache, because I use it for other performance improvements.

In the section “General Settings”(Performance>General Settings), enable “CDN” and use “Generic Mirror” as “CDN Type”. “Save all Settings”.

Go to the “CDN” section (Performance>CDN). Find the “Configuration” section and insert your new subdomain in “Replace site’s hostname with”.

“Test Mirror” and (if “Test passed”) “Save all Settings” again.

You can take a look at the different configurations on this page (default configurations must work well).

We have configured the new “CDN” and it will be used for the new uploads and for the assets, but we can change also the images and uploads in older posts.

To do that in the top of the same page (Performance>CDN), you can find a button “modify attachment URLs”. Click on it, insert your blog/page domain (not the new “CDN” subdomain) in “Domains to rename” and click “Start”. In a moment all your older images will be served through your new CDN.