We use Cloudflare as our DNS server. But, Cloudflare is much more than a DNS server. It can be used as a content delivery network (CDN).
A CDN is a geographically distributed group of servers that cache content close to end users. Let's say that a user from London is hitting a website that has a JavaScript file hosted in Chicago. That JavaScript file has to travel all the way from Chicago to London. This means the site will load slowly.
A CDN will have a copy of that JavaScript file in London itself. In this way for that user, that JavaScript file will be loaded from the London server and not from the Chicago server. This is what a CDN primarily does.
Here's how we set up Cloudflare as a CDN for our Rails applications.
We need a subdomain that will act as a CDN. For NeetoCal, we use https://cdn.neetocal.com as the subdomain. You can use any subdomain you want.
To set up this subdomain, we need to follow these steps.
CNAME
.*
.If we already have a CNAME
record for *
that handles all the subdomains,
then we don't need to create a new one.
In the previous step, when creating a new CNAME
record, by default, Cloudflare
will enable proxy for each record.
Once the Proxy status column is turned on, it will display 'Proxied' as shown below.
When we turn on "Proxy", then the DNS queries will resolve to the Cloudflare IP address instead of the target. It means Cloudflare will get all the requests and then Cloudflare in turn will forward those requests to the target.
Let's say that a user from Paris loads a webpage which is hosted in Chicago and Cloudflare has a server in Paris. When "Proxy" is turned on, then when the user makes the first request to the server, that request will go to Cloudflare. Cloudflare doesn't have the JavaScript file, so Cloudflare will forward that request to the server. The server will send that JavaScript file to Cloudflare. Cloudflare will cache this JavaScript file and serve the JavaScript file to the user.
Two seconds later, another user from a different part of Paris hits the same webpage. This time, Cloudflare has a cached copy of the JavaScript file and Cloudflare will serve the JavaScript from the server in Paris itself.
This has two benefits. The first benefit is that the user gets to see the webpage really fast. The second benefit is that the server cost is a lot lower since fewer requests need to be served by the server in Chicago.
Cloudflare can only cache files that are stored on the domain that is proxied through Cloudflare. If we have an image file that is stored on Amazon S3 and is accessed via a direct S3 URL, then Cloudflare won't be able to cache it.
Cloudflare caches are based on file extension and not by MIME type. Here is the list of file extensions that will be cached by default. HTML is not on this list.
Cloudflare allows us to cache other file types by setting up suitable page rules.
When utilizing Cloudflare as a CDN, it's crucial to configure our Rails app to
serve assets with specific Cache-Control
headers. This ensures optimal caching
behavior for resources.
The Rails app should serve assets with a header similar to the one given below.
cache-control: public, max-age=31536000
The cache-control
must be public and max-age
must be a positive value for
Cloudflare to
cache the resource.
For this, we need to modify the Rails configuration file
config/environments/production.rb
.
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=31536000'
}
Here, Cache-Control
is set to 'public', allowing any cache (including
Cloudflare) to store the resource. The max-age
is specified as 31,536,000
seconds (one year), indicating how long the cache should retain the object
before considering it stale.
asset_host
in Rails.We added the secrets for the asset_host
in our Rails application's
config/secrets.yml
file.
production:
asset_host: <%= ENV["ASSET_HOST"] %>
We also added an environment variable called ASSET_HOST
that contains our new
CDN host URL.
ASSET_HOST=cdn.neetoX.com
Once this is done all asset URLs will point to https://cdn.neetoX.com
.
Once all the setup is done, it can take a few hours for the changes to be
reflected. Hit the page and see the response header of .js
file.
If the response header cf-cache-status
had a value of HIT
then that means
Cloudflare is serving that asset from its cache.
If this blog was helpful, check out our full blog archive.