Docker mirror

Every container that you build will start from a base image that you'll pull from a Docker registry. For example:

FROM ubuntu:20.04

When you aim for reliable and stable builds this is problematic.

  • Tags are not immutable. ubuntu:20.04 can and will be overwritten when a new minor Ubuntu 20.04 version is released. The actual OS version that underpins your container now depends on when the container was built (and the base image pulled). This is also problematic when debugging issues: even though you build a container locally and in production at the same time, and from the same Dockerfile; you can end up with wildly different containers depending on which base image is in cache.

  • Images can and will be deleted. There's zero guarantee that the image will remain in the registry. For example, Nvidia actively removes old nvidia/cuda base images from Docker Hub. Also, this manifests itself only when you build a container from scratch (without the base image in the build cache) - leading to random build failures (e.g. when a new developer joins your team, or when you provision a new build server) that are very hard to track down, with no other recourse than updating your base image - which is not something you want to do under time pressure, as many things might break down the line.

  • Most images are hosted on Docker Hub, which aggressively rate limits even on paid plans - which can be problematic on build servers. Alternative registries that run pull-through caches like Amazon ECR only have a fraction of the images of Docker Hub.

StableBuild's Docker mirror solves all of these problems by operating an immutable mirror to Docker Hub. To pull through StableBuild you just prefix any image with your registry domain, e.g.:

FROM your-domain.dockermirror.stablebuild.com/ubuntu:20.04

We then pull the ubuntu:20.04 image from Docker Hub, and store the image in our cache. When you pull the same tag again, we just return the cached image. This image is now immutable. It'll never be overwritten, and it'll never be deleted. There are also no rate limits when pulling this image.

Because we realize you might target multiple architectures - e.g. developers use Apple silicon (ARM), but you deploy on x86 machines - we also cache all available architectures for images.

That's it. Your base images are now stable and reliable. 🎉

Tips & tricks

Don't use overly wide tags

Because any image will become immutable you want to be specific in the image / tag you pull. E.g. don't use ubuntu:latest or ubuntu:20.04 but rather ubuntu:focal-20230801 (the Ubuntu 20.04 release from Aug 1, 2023). If you want to remove an image, go to Dashboard > Docker mirror, and remove the tag under "Cached tags". We'll then re-fetch the image the next time you pull.

Private repositories

We don't support pulling from private repositories, as you're most likely control overwriting tags or deleting images yourself. If this is a usecase that you're interested in, please let us know at support@stablebuild.com.

Registry mirror

When you can't change the tags in your Dockerfile - for example, you build containers for your customers - you can also use StableBuild as a registry mirror. This will behave exactly the same as manually prefixing the base image in your Dockerfile; but does require you to configure the mirror on every server.

To do so, add the following to your Docker configuration (e.g. Docker > Settings > Docker Engine on macOS, or edit /etc/docker/daemon.json on Linux):

"registry-mirrors": [ "https://your-domain.dockermirror.stablebuild.com" ]

If you build using Kaniko, add the following flag:

--registry-mirror https://your-domain.dockermirror.stablebuild.com

How about pinning to a hash?

Rather than pin to a tag, you can also pin to a SHA hash in your Dockerfile - which will return the same image every time. E.g.:

FROM ubuntu@sha256:c9cf959fd83770dfdefd8fb42cfef0761432af36a764c077aed54bbc5bb25368

Unfortunately this has two downsides:

  • The SHA hash is architecture dependent. The hash above will return an x86 container. This blocks you from using hashes if you have multi-architecture containers (e.g. your developers are using Macs, and you deploy on x86).

  • The images can still be deleted from Docker Hub; breaking your build.

StableBuild supports pulling from a SHA hash as well, but you'll most likely will want to pull from a tag instead.

v1 manifests are not fully cached

Very old base images, e.g. ubuntu:trusty-20150320, are in Docker Hub with an old manifest version. When pulling from a base image like this you'll see:

[DEPRECATION NOTICE] Docker Image Format v1, and Docker Image manifest version 2, schema 1 support will be removed in an upcoming release. Suggest the author of dockermirror.stablebuild.com/ubuntu:trusty-20150320 to upgrade the image to the OCI Format, or Docker Image manifest v2, schema 2. More information at https://docs.docker.com/go/deprecated-image-specs/

For these base images we'll cache the main manifest, but not architecture specific ones; and we also do not cache layers for these images. If you rely on any of these base images it's best to update.

Layers larger than 5GB

Layers that are larger than 5GB are not cached while you download, but asynchronously. It might take a few minutes (or even more) before these are stored in StableBuild. You can observe the x-in-sb-cache header which is returned when fetching layers.

Last updated