<?xml version="1.0" encoding="utf-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom">
     <title>BigBinary Blog</title>
     <link href="https://www.bigbinary.com/feed.xml" rel="self"/>
     <link href="https://www.bigbinary.com/"/>
     <updated>2026-05-19T04:01:47+00:00</updated>
     <id>https://www.bigbinary.com/</id>
     <entry>
       <title><![CDATA[Using Cloudflare as CDN for Rails applications]]></title>
       <author><name>Abhijith Sheheer</name></author>
      <link href="https://www.bigbinary.com/blog/using-cloudflare-as-cdn-for-rails-applications"/>
      <updated>2023-12-19T12:00:00+00:00</updated>
      <id>https://www.bigbinary.com/blog/using-cloudflare-as-cdn-for-rails-applications</id>
      <content type="html"><![CDATA[<p>We use <a href="https://www.cloudflare.com/">Cloudflare</a> as our DNS server. But,Cloudflare is much more than a DNS server. It can be used as a content deliverynetwork (CDN).</p><p>A CDN is a geographically distributed group of servers that cache content closeto end users. Let's say that a user from London is hitting a website that has aJavaScript file hosted in Chicago. That JavaScript file has to travel all theway from Chicago to London. This means the site will load slowly.</p><p>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 andnot from the Chicago server. This is what a CDN primarily does.</p><p>Here's how we set up Cloudflare as a CDN for our Rails applications.</p><h2>1. Configure CNAME record for CDN subdomain in Cloudflare</h2><p>We need a subdomain that will act as a CDN. For<a href="https://www.neeto.com/neetocal">NeetoCal</a>, we use https://cdn.neetocal.com asthe subdomain. You can use any subdomain you want.</p><p>To set up this subdomain, follow these steps.</p><ol><li>Add a new record with the <strong>type</strong> <code>CNAME</code>.</li><li>In the <strong>name</strong> field, enter <code>*</code>.</li><li>In the <strong>target</strong> field, enter the URL where the Rails app is deployed.</li></ol><p>If we already have a <code>CNAME</code> record for <code>*</code> that handles all the subdomains,then we don't need to create a new one.</p><p><img src="/blog_images/2023/using-cloudflare-as-cdn-for-rails-applications/create-cname-record.png" alt="Creating  record"></p><h2>2. Turn on the Proxy feature in Cloudflare</h2><p>In the previous step, when creating a new <code>CNAME</code> record, by default, Cloudflarewill enable proxy for each record.</p><p>Once the <strong>Proxy status</strong> column is turned on, it will display 'Proxied' asshown below.</p><p><img src="/blog_images/2023/using-cloudflare-as-cdn-for-rails-applications/proxy-status-on.png" alt="&quot;Proxy status&quot; turned ON"></p><p>When we turn on &quot;Proxy&quot;, then the DNS queries will resolve to the Cloudflare IPaddress instead of the target. It means Cloudflare will get all the requests andthen Cloudflare in turn will forward those requests to the target.</p><p>Let's say that a user from Paris loads a webpage which is hosted in Chicago andCloudflare has a server in Paris. When &quot;Proxy&quot; is turned on, then when the usermakes the first request to the server, that request will go to Cloudflare.Cloudflare doesn't have the JavaScript file, so Cloudflare will forward thatrequest to the server. The server will send that JavaScript file to Cloudflare.Cloudflare will cache this JavaScript file and serve the JavaScript file to theuser.</p><p>Two seconds later, another user from a different part of Paris hits the samewebpage. This time, Cloudflare has a cached copy of the JavaScript file andCloudflare will serve the JavaScript from its server in Paris.</p><p>This has two benefits. The first benefit is that the user gets to see thewebpage really fast. The second benefit is that the server cost is a lot lowersince fewer requests need to be served by the server in Chicago.</p><h3>What all things Cloudflare can cache</h3><p>Cloudflare can only cache files that are stored on the domain that is proxiedthrough Cloudflare. If we have an image file that is stored on Amazon S3 and isaccessed via a direct S3 URL, then Cloudflare <strong>won't</strong> be able to cache it.</p><p>Cloudflare caches are based on file extensions, not MIME types.<a href="https://developers.cloudflare.com/cache/about/default-cache-behavior/#default-cached-file-extensions">Here</a>is the list of file extensions that will be cached by default. HTML is not onthis list.</p><p>Cloudflare allows us to cache other file types by setting up suitable<a href="https://developers.cloudflare.com/cache/how-to/create-page-rules/">page rules</a>.</p><h2>3. Set appropriate Cache-Control headers in Rails</h2><p>When utilizing Cloudflare as a CDN, it's crucial to configure our Rails app toserve assets with specific <code>Cache-Control</code> headers. This ensures optimal cachingbehavior for resources.</p><p>The Rails app should serve assets with a header similar to the one given below.</p><pre><code>cache-control: public, max-age=31536000</code></pre><p>The <code>cache-control</code> must be public, and <code>max-age</code> must be a positive value forCloudflare to<a href="https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-behavior">cache the resource</a>.</p><p>For this, we need to modify the Rails configuration file<code>config/environments/production.rb</code>.</p><pre><code class="language-ruby">config.public_file_server.headers = {  'Cache-Control' =&gt; 'public, max-age=31536000'}</code></pre><p>Here, <code>Cache-Control</code> is set to 'public', allowing any cache (includingCloudflare) to store the resource. The <code>max-age</code> is specified as 31,536,000seconds (one year), indicating how long the cache should retain the objectbefore considering it stale.</p><h2>4. Configure <code>asset_host</code> in Rails.</h2><p>We added the secrets for the <code>asset_host</code> in our Rails application's<code>config/secrets.yml</code> file.</p><pre><code class="language-yml">production:  asset_host: &lt;%= ENV[&quot;ASSET_HOST&quot;] %&gt;</code></pre><p>We also added an environment variable called <code>ASSET_HOST</code> that contains our newCDN host URL.</p><pre><code>ASSET_HOST=cdn.neetoX.com</code></pre><p>Once this is done all asset URLs will point to <code>https://cdn.neetoX.com</code>.</p><h2>5. Verify changes</h2><p>Once all the setup is done, it can take a few hours for the changes to bereflected. Hit the page and see the response header of <code>.js</code> file.</p><p>If the response header <code>cf-cache-status</code> had a value of <code>HIT</code>, then that meansCloudflare is serving that asset from its cache.</p><p><img src="/blog_images/2023/using-cloudflare-as-cdn-for-rails-applications/browser-console-cache-status.png" alt="Viewing cache status in browser console"></p>]]></content>
    </entry>
     </feed>