As promised in my last missive, this post will take you through creating a custom domain alias for the files being served by a DigitalOcean Spaces bucket. What does that mean? Well, DigitalOcean Spaces is a cloud-based file storage that serves media like images, video, etc. This media can take-up a lot of storage, especially for an application like Mastodon, so it makes sense to offload it to a service is relatively inexpensive and prevents you from running into storage caps. Another benefit is that you can move your application more easily between hosting services without worrying about moving all the files, which often is the biggest time suck for migrations.
So that’s why one might use an S3-compatible storage service like Spaces for an application like Mastodon which I discussed in my last post, but why do you need a custom domain for serving those files? There are a few reasons:
- It makes moving between S3-cloud-based storage providers easier. For example, say I want to move between Spaces and my own, self-hosted Minio S-3 object storage server eventually, that would be possible without breaking links by keeping the domain consistent regardless of storage provider.
- When using a custom domain with Spaces you can actually access their content delivery network (CDN) which means the files are cached around their global network and files will be served faster.
- Finally, custom domains are awesome, how much better is a domain like custom domain like https://ds106.social versus https://ds106social.fra1.digitaloceanspaces.com …. no contest, right?
Ok, so now that you know the what and the why, let’s get into the how-to for DigitalOcean Spaces. The first piece is making sure you can point the domain you want to map on a Spaces bucket to DigitalOcean’s nameservers. DNS can be confusing, but the piece here to keep in mind that for this to work is the entire domain needs to be pointed at DO’s nameservers, and this means you would control the DNS zones and pointing from their networking interface.This is not necessarily bad, it’s essentially the same thing you do with Cloudflare, but an issue could arise if you already have this domain managed elsewhere and changing the DNS records to a new service could mean overhead and downtime.
I just happened to have the ds106.social domain I was thinking about running Mastodon on, but having already setup the server on social.ds106.us, it was a simply redirecting traffic. So, I decided to point ds106.social to DigitalOcean’s custom nameservers, which are ns1.digitalocean.com, ns2.digitalocean.com, and ns3.digitalocean.com. The nameservers are usually changed where ever you registered the domain. After that, you go to the Networking area of Digital ocean and add the domain, which will then allow you to manage and add new DNS records:
Once the domain is added, return to the Spaces bucket and enable the CDN option in settings:
Once the CDN option is enabled you will be asked to select a subdomain to load the files over, and now that you have pointed your domain’s nameservers to DigitalOcean you can do this. You can choose the domain ds106.social and define the subdomain.
I used files.ds106.social, and this will automatically create a CNAME (or alias) that will make all the files served over ds106social.fra1.digitaloceanspaces.com also work over ds106social.fra1.cdn.digitaloceanspaces.com for the CDN, but most importantly served over files.ds106.social. Below are three examples of the same file resolving over all three domain names:
https://ds106social.fra1.digitaloceanspaces.com/accounts/avatars/109/309/621/412/056/867/original/f758838c34a58ad2.jpg
https://ds106social.fra1.cdn.digitaloceanspaces.com/accounts/avatars/109/309/621/412/056/867/original/f758838c34a58ad2.jpg
https://files.ds106.social/accounts/avatars/109/309/621/412/056/867/original/f758838c34a58ad2.jpg
And that is the magic of alias domain mapping! Digital Ocean provides the Let’s Encrypt certificate that works for all the above domains, and now the ds106 Mastodon instance defaults to the files.ds106.social domain for all media, which is quite slick. The subdomain, files.ds106.social for this example, is a CNAME hostname, pointed to the value ds106social.fra1.cdn.digitaloceanspaces.com. —this makes files.ds106.social an alias of ds106social.fra1.cdn.digitaloceanspaces.com.
I learned this the hard way given I was initially confused about whether I could point a subdomain from another service like Cloudflare to the Spaces bucket (you can do this on AWS I’m pretty sure), and the short answer is you can’t. You have to point nameservers and then use DigitalOcean’s networking option to manage the domain, subdomain and SSL certificate.
Final step would be to add the environmental variable for the new alias to your .env.production file in Mastodon:
S3_ALIAS_HOST=files.ds106.social
So my .env.production configuration for the object storage now looks like this, which is just the additional of the S3_ALIAS_HOST variable:
S3_ENABLED=true
S3_PROTOCOL=https
S3_BUCKET=ds106social
S3_REGION=fra1
S3_HOSTNAME=fra1.digitaloceanspaces.com
S3_ENDPOINT=https://fra1.digitaloceanspaces.com
S3_ALIAS_HOST=files.ds106.social
AWS_ACCESS_KEY_ID=yourspacesaccesskey
AWS_SECRET_ACCESS_KEY=yoursupersecretspacesaccesskey
And that’s all folks! If everything is working as it should be your domain alias is working and you can test that by inspecting any image or avatar and checking the domain file URL.
NB: If I were a better guide writer I would re-do adding this subdomain to Spaces given I can’t remember the exact steps of how the subdomain was created (complicated by the fact I uploaded a certificate from Cloudflare while I was trying the old method) and how it creates the certificate, but I believe it is automatic and you can create a new subdomain such as files, but I really don’t want to delete this subdomain and do it again for the sake of this post given it will create a bit of havoc on the server 🙂
Pingback: The Allure of Mastodon | bavatuesdays