As you may have seen, Docker Hub made a dramatic shift in policy this week, and effectively gave a 30 day eviction notice to almost all community-run images.
They’ve now made an apology to ‘clarify’ a few details, and helpfully take some of the hard edges off, but this still highlights a big problem. Fortunately, there are solutions.
As initially described, this would’ve been catastrophic: Docker Hub has been used as the default host in tooling, tutorials, demos, blog posts, scripts, deployment definitions, CI builds and more for many years, and all those references were going to break – a self-inflicted left-pad for the Docker ecosystem. In their updated policy, it appears they now won’t remove any existing images, but projects who don’t pay up will not be able to publish any new images, so they’ve effectively lost control of the namespace they used to deploy to their communities unless they purchase a full team subscription. Many will not do so.
This is an interesting challenge. Even if the existing images aren’t removed, the direction of travel for Docker Hub is now clear: they don’t want to host the core of the Docker community any more, no more freebies, pay up or go elsewhere (not unreasonable, but something of a rugpull after a full decade of the opposite).
As a small/open-source/community/hobbyist image publisher, or if you depend on Docker Hub for free image publishing in any capacity, you now have a problem. They don’t want you there. You’re explicitly not their audience, and the rules will likely tighten further. This isn’t unreasonable – it’s their service and hosting isn’t free – but it’s worth considering explicitly and reacting accordingly. If you’re not a paying Docker Hub customer, it’s time to leave Docker Hub.
The hard part is what to do instead.
Self-hosting a registry is not free, and it’s more work than it sounds: it’s a proper piece of infrastructure, and comes with all the obligations that implies, from monitoring to promptly applying security updates to load & disk-space management. Nobody (let alone tiny projects like these) wants this job.
Alternatively, there are plenty of other free hosted Docker registries, and paid services too, but migrating to one directly feels a lot like you’re just going to hit the exact same problem 6 months from now, and have to change your image references everywhere all over again.
What if you could use your own fixed registry URL, on your own domain & entirely under your control, but without having to self-host forever, or even commit to any particular registry, or handle all the bandwidth & storage costs?
We’re looking for a way to:
- Reference your images from an address you fully control (
docker pull docker.my-org.example.com/org/my-image
) - Do so whilst still being able to use any registry hosted elsewhere, or self-hosted ourselves.
- Avoid storing, loading, or serving the content separately. For now at least, there’s quite a few other registries who will happily do this for public images for free, and even if there weren’t we’d like to avoid extra latency or ingress & egress fees from proxying this traffic.
- Be able to change which backing registry we’re using in future, without any of the image addresses ever changing again.
What if I told you that’s actually super easy?
Exploring the possibilities
Let’s talk about how this could work, and then we’ll dig into what docker pull
actually does, and put together a quick solution (if you just want to know how to do this immediately, now’s the time to skip to the end).
Docker’s registry API runs on fairly simple HTTP, and HTTP APIs have a few different solutions available for situations like this.
The classic ‘host under your own domain’ solution is to use CNAMEs at the DNS level. This means setting up a DNS record under your domain, which points to a domain elsewhere, effectively defining an alias. When a client tries to connect, they’ll lookup your-registry.example.com
, find a record referencing the backing registry (registry.hub.docker.com
, for example), and then all requests will get sent over there.
If this worked here, that’d be great! Zero hosting required, just handle it on the DNS level.
Unfortunately, this requires that target server to correctly handles HTTP requests with your 3rd party domain name in the Host
header, knowing that they should be processed as requests to the real service. For Docker Hub at least, that’s not possible (not for free certainly – although like many other services this might be offered as a paid addon). Requests sent to Docker Hub with the wrong hostname sim