Because I use Cloudflare to manage my domains and Backblaze for backups, it only made sense to take advantage of their Bandwidth Alliance for creating my own CDN. This has been incredibly helpful for image hosting for this knowledge base, however, I recently noticed that caching wasn't working as it should.
The overall problem started when I was adding a parking page for a domain I recently purchased. The background image was hosted on B2 and the image was supposed to be cached by Cloudflare. However, each time the page loaded, it would pull the image from the origin instead of the cache. I checked this on my knowledge base and found it was doing the same thing.
Additionally, on my knowledge base, each reload would fetch search.json
from the origin. This slowed down each page load considerably, especially on the initial load. By default, Cloudflare does not cache JSON files without being forced by a Page Rule.
After doing a lot of research, I realized there were three things that I needed to do that weren't configured...
- Configure CORS in B2 for the bucket everything is stored in.
- Add cache-control to the bucket in B2.
- Reconfigure the Page Rules on Cloudflare.
- Log into Backblaze and open Buckets
- Find your bucket and open CORS Rules
- Depending on your needs, adjust the CORS setting accordingly. For my needs, I changed the CORS setting from
Do not share any files with any origin
toShare everything in this bucket with every origin
.
NOTE: Your mileage may vary, but you should definitely understand the implications of such a change prior to doing it.
- Log into Backblaze and open Buckets
- Find your bucket and open Bucket Settings
- In the Bucket Info section, add the following:
{"cache-control":"max-age=86400"}
NOTE: This step may not be necessary as it's likely being overriden by the Page Rules on Cloudflare. However, it can't hurt to have this added to the bucket as a failsafe in case any Page Rules on Cloudflare change at any point.
- Log into Cloudflare and open your domain.
- Navigate to Page Rules
- Since my CDN content doesn't change very frequently, I configured the CDN rule with the following rules:
"<subdomain.example.com/*"
* **Browser Cache TTL**: a day
* **Cache Level**: Cache Everything
* **Edge Cache TTL**: a month
* **IP Geolocation Header**: On
* **Origin Cache Control**: On
Having the Origin Cache Control option set to On will control what assets Cloudflare, and the browser, will cache.
"www.example.com/*"
* **Auto Minify**: Select HTML/CSS/JS
* **Browser Cache TTL**: 30 minutes
* **Cache Level**: Cache Everything
* **Edge Cache TTL**: 2 hours
The cache level can likely be set to Standard, however, since the cache TTL for both the browser and edge are set to the minimum, it's likely not going to be a problem with updates made to the site. Should it interfere with new content loading, I'll adjust it accordingly.
Once these adjustments were made, images and additional content are now being cached appropriately. This took a lot of trial and error, but was a worthwhile exercise that has now improved page load speed tremendously.
I wrote a separate Gist on how to rewrite the subdomain url for stripping the /file/<bucket-name>
prefix from the url. It creates a much cleaner url and protects the origin that much more by not displaying it in the url. It can be found here
- https://community.cloudflare.com/t/cache-images-from-backblaze-b2/63104/7
- https://community.cloudflare.com/t/solved-origin-cache-control-and-expires-headers-have-no-effect-cloudflare-is-incompatible-with-imunify360-solution-disable-webshield/7858*5
- https://gist.github.com/charlesroper/f2da6152d6789fa6f25e9d194a42b889
- https://community.cloudflare.com/t/what-is-origin-cache-control/30606
- https://stackoverflow.com/questions/11560101/caching-json-with-cloudflare
- https://jross.me/free-personal-image-hosting-with-backblaze-b2-and-cloudflare-workers/
- https://github.com/phistrom/b2-remove-prefix
Super helpfull ! Thanks :)