Building custom domains for your SaaS is not always easy, especially when certificates get involved.
With Caddy it becomes very easy!
On The Caddy Side
{
email dns@marco.ninja
# Caddy asks this endpoint if it shall handle traffic for a domain
on_demand_tls {
ask https://backend.local/internal/custom-domain-check/
}
}
# Accept all domains that pass the ask endpoint
https:// {
tls {
on_demand
}
handle /.well-known/health {
respond "200 OK" 200
}
reverse_proxy https://backend.local {
header_down -server
}
}
On The App Side
Simply implement a CRUD UI for your customer to add their custom domain.
Then add an endpoint that Caddy can ask if a domain is valid for it to serve, might look something like this:
from django.http import HttpResponse
from core.models import Project
def custom_domain_check(request):
"""Check if we are authorized to issue certificates for the given domain"""
try:
domain = request.GET["domain"].lower()
Project.objects.get(custom_domain=domain)
except:
return HttpResponse(status=404)
return HttpResponse(status=200)
Scaling and HA Considerations
- Caddy can be scaled, if you give it a storage engine that is HA, might be easiest to use the one for the DB you are hosting already
- Traffic into the Caddy instances needs to be balanced on layer 3, no CloudFlare CDN possible (at least not easily)
Tip
Need help getting your SaaS infrastructure and custom domains up and running?