Using Digital Ocean Spaces and KeyCDN within Statamic
If your website is going to be handling quite a few assets and if you have any kind of global reach, it’s definitely worth considering outsourcing the storage and delivery of your assets. Or, perhaps we can make it simple enough that you should just do it anyway 😎
Spaces are Digital Ocean’s own object storage offering backed by an API which is 100% compatible with Amazon S3s API.
So why bother using Space over S3? After all, Statamic comes with a baked in S3 driver. The big selling point for our agency, who are looking after a number of websites, is that they are fixed in price. For $5/month you get 250GB storage and 1TB of transfer. That’s as complicated as it gets. You only pay extra if you go over that. Trying to figure out what your S3 bill will look like will make your head explode and that makes it a hard sell for clients and a pain for us to bill.
OK, so how about KeyCDN? In my experience, KeyCDN are great at rolling out the latest and greatest new technologies – HTTP/2, brotli compression, Let’s Encrypt etc. I wont run down their full feature list but I will say that it’s a pretty fully-featured service, it’s simple to set up and it is very competitively priced. You can also trial the service for 30 days for free.
Get up and running with Spaces
Once you’re signed up and logged in with Digital Ocean, create a new Space. Currently you can select New York, Amsterdam or Singapore. Don’t worry about the limited selection as we’ll actually be serving the images via KeyCDN who have 33 locations. Make sure you add a name, location and select Restrict File Listing. You can then go ahead and create the Space.
Now you’ll need to generate an access key:
- From the left-hand menu in the Digital Ocean dashboard, navigate to
API
- Under Spaces access keys, click the
Generate New Key
button.
The last step is to create a new asset container within Statamic and wire it up to the Space we just created. Thankfully, this is extremely easy as the Spaces API directly matches the S3 API, so we can reuse Statamic’s S3 implementation. The only gotcha is that we will have to create the container manually with a yaml
file rather than through the control panel, otherwise we can’t input the correct Spaces endpoint. Within your Statamic project, create a new yaml
file within site/content/assets
. The contents of this file should look like:
title: Whatever you like
driver: s3
key: your Space key
secret: your Space secret
bucket: your Space name
region: your Space region
endpoint: your Space endpoint
A completed config might look like this:
title: Global assets
driver: s3
key: xxxxxx
secret: xxxxxx
bucket: statamic-assets
region: ams3
endpoint: ams3.digitaloceanspaces.com
You can also add path: a/sub/directory
if you would like to limit the container to a specific folder within your Space.
Go and give that a test, it should just work. You should be able to see any assets added within Statamic pop up with your Space immediately. You can navigate into your Space within the Digital Ocean dashboard to view the contents.
Going global
Assets shouldn’t be served directly from object storage such as S3 or Spaces. Whilst these services are great for resilient storage, they are not tuned for performance and your assets will only be served from a single location. A CDN on the other-hand, is geared specifically for performance and global delivery.
First, sign up/in to KeyCDN. Within the dashboard, navigate to Zones
then click Add Zone
. We’re going to create a pull zone. This will “suck in” the assets from Spaces automatically, without any need for us to push any assets into the CDN.
- Add the zone name
- Make sure you have the zone type set to pull, although this is the default
- Leave the advanced features for now.
- Under the origin URL, add in your Space URL, such as
https://your-space.ams3.digitaloceanspaces.com
and click Save. - It’ll take a few minutes to configure itself.
Once you’ve got Status active
for the pull zone, go ahead and test your assets are available. Copy a URL for one of your assets in Statamic, which should look something like:
your-space.ams3.digitaloceanspace.com/your-image.jpg
Swap out everything before the filename and extension for the KeyCDN Zone URL. This should now look something like:
your-zone-cbbe.kxcdn.com/your-image.jpg
This should load up exactly the same image. You can open Chrome’s Network tab and check the headers:
You should see the cache status, an expires header, the canonical link to the original image and also the edge location you were served the image from, which in my case is uklo
(London, UK). Perfect 🌎
Serving images via a CDN in Statamic
At this point, we have our images mirrored on a CDN but Statamic will still be serving the images directly from Spaces. I’m sure there’s several ways to address this but here’s what I’ve arrived at.
Firstly, let’s create an environment variable which contains our CDN zone URL. Open up your .env
file within the root of your Statamic project and create a new variable such as CDN
with your zone URL.
APP_ENV=dev
CDN="http://your-zone-cbbe.kxcdn.com"
I feel like this is a pretty neat solution, as if our CDN URL was to change, we can simply replace it here and the change would roll out site-wide. We can also choose not to serve from a CDN in a given environment.
So how can we use this? Let’s say that we have an asset field called image
.
{{ assets:image }}
<img src="{{ env:CDN }}/{{ path }}">
{{ /assets:image }}
Now if you inspect the image, you should see you’re being served the image over the CDN zone we set up 🎉
Bonus points
There are two further enhancements we can easily make to improve this set up. First up, we probably don’t want to serve our assets from an ugly URL that has nothing to do with your domain. KeyCDN lets us set up Zonealiases to solve exactly this problem. You’ll need to set up a CNAME record with your DNS provider. For example, you may want to set up a CNAME such as:
cdn.yourdomain.com 120 IN CNAME <yourzonename>-cbbe.kxcdn.com
Once the record is in place:
- Navigate to
Zonealiases
within the KeyCDN dashboard and clickAdd Zonealias
- Add your alias, such as
cdn.yourdomain.com
and select the zone we made earlier - You’ll need to wait a a short while for this to take effect, around 3–5 minutes in my experience
- Once you see your images appear under
cdn.your-domain.com/your-imnage.jpg
you’re good to go
The final piece of the puzzle is to serve everything via https, which you will likely be doing for the rest of your site. Thankfully, KeyCDN has you covered and offers Let’s Encrypt certificates zones.
- Navigate to your zone and click
Manage
and thenEdit
- Check
Show Advanced Features
- Scroll down to
SSL
and selectletsencrypt
- You’ll probably also want to set
Force SSL
toenabled
- Save the changes then navigate back over to
Zonealiases
- Click
edit
on your zonealias, don’t change anything, then clickSave
. This will reconfigure your alias to be served over https - Give it another 3–5 minutes to do its thing then try hitting one of your images again.
Bingo 🔥