How to Create a Self Hosted CDN With WordPress

How to Create a Self Hosted CDN With WordPress

You will greatly improve the loading time of your website by spreading images, CSS and Javascript files across a server network by using a Content Delivery Network service (also known as a CDN). Nevertheless, if you are on a budget and are unable to afford a commercial CDN service, you can always simulate one by developing and hosting a subdomain on the same server as your website. While this kind of defeats a CDN’s intent, by increasing the number of simultaneous downloads, it will still increase the website’s loading time.

I will use the following for this tutorial: cPanel web hosting;Shell access to your hosting account; FollowSymLinks allowed Apache web server; WordPress WP Super Cache plugin.

So let’s continue.

Step 1: Creating a Subdomain for the CDN

Begin by logging in and clicking on the “Subdomains” icon in your cPanel account.

Name the CDN subdomain you want to use. I use the domain “ashokkuikel.com” for this tutorial, so I will use the subdomain “staticcdn.ashokkuikel.com” for my CDN:

Important: note that the subdomain’s document root is outside the public html directory. It is necessary to do so to prevent any effect on your subdomain from the “.htaccess” file located in “public html.” It is necessary to create the “subdomains” directory at the same level as “public html.”

If you have SSL enabled on your website, allowing SSL for your CDN subdomain is also imperative. Depending on how your web hosting provider set up your server, when you’ve built the subdomain, a free SSL certificate could be issued and enabled automatically (AutoSSL). To check this, simply use https:/staticcdn.ashokkuikel.com to point your web browser and see if the padlock appears in the address bar:

You can contact your web hosting company though you find any issues with your SSL certificate.

However, it should be open to your CDN subdomain at this stage, it is still empty. You can still try to ensure that it correctly resolves even if it returns an error message:

Step 2: Creating Symbolic Links

You will need to create symbolic connections to make the media files available through the CDN subdomain. Often known as a soft link, a symbolic link is a file pointing like a shortcut to another file. Since everything in Linux is a file, a symbolic connection pointing to a directory can also be created.

To do this, go back to your cPanel control panel and click on the “Advanced” panel “Terminal” icon: on the next tab, click on “I understand and want to continue” to start a protected shell session:

Now, to create symbolic links, you will need to type the following commands. I assume that WordPress will be installed at the root of your main domain for this tutorial (i.e.:/public html). Of course, you need to replace your CDN subdomain name with “staticcdn.ashokkuikel.com”:

ln -s ~/public_html/wp-admin ~/subdomains/staticcdn.ashokkuikel.com/wp-admin
ln -s ~/public_html/wp-content ~/subdomains/staticcdn.ashokkuikel.com/wp-content
ln -s ~/public_html/wp-includes ~/subdomains/staticcdn.ashokkuikel.com/wp-includes

If you built other directories outside the framework of WordPress, you could create additional symbolic ties in the same manner.

First, we’ll make sure that the subdomain helps us to access the files. I will try to pull the style.css file from the current WordPress theme in this case: if everything works fine, move on to the next stage.

Step 3: Prevention of HTML Content Indexing Search Engine

To avoid duplicating content problems, you must prevent any HTML content from being indexed by search engines. Build a file called “robots.txt” and insert the following content for this purpose:

User-agent: *
Disallow: /
Allow: *.css?*
Allow: *.js?*
Allow: *.jpg?*
Allow: *.gif?*
Allow: *.png?*
Allow: *.jpeg?*
Allow: *.css
Allow: *.js
Allow: *.jpg
Allow: *.gif
Allow: *.png
Allow: *.pdf
Allow: *.jpeg
Allow: *.woff2
Allow: *.woff
Allow: *.ttf

If you need to allow additional file extensions to be indexed, simply add them there. Upload the file to the root directory of the subdomain (i.e.: ~/subdomains / staticcdn.ashokkuikel.com/) until done.

Step 4: Preventing Visitors From Browsing Your Subdomain Directory

You will disallow “indexes” to prevent users from accessing all the files accessible on your CDN subdomain. To do so, insert the following content into the ~/subdomains / staticcdn.ashokkuikel.com/ directory, and upload it to your server.

Options All -Indexes

Step 5: Forcing HTTPS Access

You can skip this move if you don’t have SSL allowed on your WordPress site.

To ensure that visitors have secure access to the CDN content, all requests made via port 80 must be redirected to HTTPS on port 443. Add this code to the “.htaccess” file content:

RewriteEngine on
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
RewriteCond %{HTTP_HOST} !^staticcdn\.ashokkuikel\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*) https://staticcdn.ashokkuikel.com/$1 [L,R,NE]

Now seek to use http:/[…] to reach your subdomain and see if your browser is redirected to https:/[…].

Phase 6: Enabling Expiration Headers

The following information must be added to the “.htaccess” file to simplify the browser caching of the files supported by the CDN:

<IfModule mod_headers.c>
<FilesMatch “\.(css|js|jpg|jpeg|gif|png|pdf|woff2|woff|ttf)$”>
Header set Access-Control-Allow-Origin “*”
</FilesMatch>
Header always set Strict-Transport-Security “max-age=31536000” env=HTTPS
Header always append X-Frame-Options SAMEORIGIN
<FilesMatch “\.(js|css|swf|ico|gif|jpg|jpeg|png|flv|pdf|woff|woff2|pdf)$”>
Header set Cache-Control “max-age=29030400”
</FilesMatch>
</IfModule>

<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault “access plus 10800 seconds”
ExpiresByType font/opentype A29030400
ExpiresByType font/truetype A29030400
ExpiresByType font/eot A29030400
ExpiresByType image/gif A29030400
ExpiresByType image/png A29030400
ExpiresByType image/jpeg A29030400
ExpiresByType image/x-icon A29030400
ExpiresByType application/pdf A29030400
ExpiresByType application/x-javascript A29030400
ExpiresByType application/javascript A29030400
ExpiresByType text/plain A86400
ExpiresByType text/css A604800
ExpiresByType application/xml A604800
</IfModule>

Step 7: Enabling Gzip Compression

It is recommended that you allow gzip compression to make your website load faster. This will greatly reduce the size of the downloaded files from your website. Again, add this to the contents of your previously created “.htaccess” file:

<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
<IfModule mod_setenvif.c>
# Old Browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
</IfModule>

<IfModule mod_headers.c>
# Make sure proxies don’t deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>

AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE image/png
AddOutputFilterByType DEFLATE image/jpeg
AddOutputFilterByType DEFLATE image/gif
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/eot
AddOutputFilterByType DEFLATE font/woff
AddOutputFilterByType DEFLATE font/truetype
AddOutputFilterByType DEFLATE font/opentype
</IfModule>

At this point, this what the content of your subdomain directory should look like:

-rw-rw-r–. 1 myuser myuser 282 Jul 31 16:39 .htaccess
-rw-rw-r–. 1 myuser myuser 249 Jul 31 16:38 robots.txt
lrwxrwxrwx. 1 myuser myuser 34 Jul 31 14:55 wp-admin -> /home/myuser/public_html/wp-admin
lrwxrwxrwx. 1 myuser myuser 36 Jul 31 15:02 wp-content -> /home/myuser/public_html/wp-content
lrwxrwxrwx. 1 myuser myuser 37 Jul 31 17:03 wp-includes -> /home/myuser/public_html/wp-includes

Step 8: Installing and Configuring the WP Super Cache Plugin

In addition to caching your WordPress content into static files for faster access, the WP Super Cache plugin will allow you to substitute the URL of each media file with the URL of your CDN subdomain.

Sign in to your dashboard for WordPress and go to Plugins > Add New. Use the keyword search to check for wp super cache.

Click the Enable button once the installation is complete and go to Settings > WP Super Cache. I’m not going to go into details on how to set up WP Super Cache, so I recommend reading this guide.

Tap the “CDN” tab and select Enable CDN Support after configuring the caching settings. Enter the subdomain URL for your CDN: you must also allow caching. Click on the tab “Free” and choose “Caching On.”

Step 9: Testing the CDN

Using our web page speed test is an easy way to make sure the CDN works properly. Enter the URL of your website and click “Start Check.” Scroll down to the “Waterfall” section once the speed check has been completed and extend the line for the style.css file: if everything works as intended, the URL will lead to the CDNsubdomain and your website will load much faster if you have already configured the WP Super Cache settings.

If you have any questions or ideas on how this tutorial can be improved, leave a comment below!

Ashok kuikel

Hi, I am Ashok Kuikel, WordPress Developer for WordPress Community. While Cloud Computing Associate and Alibaba MVP and ACA for Cloud Professional. You can follow me on Social Media, GitHub, and via my Blog Channels.

Leave a Reply

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