DockerHub

Regarding the latest changes with DockerHub, starting March 1 2025, the throttling limits for unauthenticated calls have been reduced.

Alternatives

Internally, we use the following process to mitigate the DockerHub rate limits. In short, we first try to replace the image with an official or mirrored alternative. If that fails, we authenticate to DockerHub with a Pro account.

  1. Search for official alternatives of the image on quay.io, ghcr.io, gcr.io, …
  2. Search for a Verified Account mirror on public.ecr.aws
  3. Check whether the docker.io (DockerHub) image is from a “Verified Publisher”, as no rate limiting should apply according to the docs
  4. Check whether you can pull the same image from mirror.gcr.io
  5. Stay on docker.io (DockerHub) and use a Pro account with imagePullSecrets (read further below)

DockerHub Authentication

Best way to keep using DockerHub is to authenticate and use your credentials (using a Docker Pro license).

The steps are:

  1. Register on docker.com for a Pro/Team/Business plan depending on your needs

  2. Create a new secret that includes your dockerhub credentials (upstream docs):

    kubectl create secret docker-registry regcred --docker-server=https://index.docker.io/v1/ --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
  3. Ensure this secret is created in every namespace that needs to pull an image from the private registry.

  4. In your container specification, you will use the following imagePullSecret upstream docs:

    spec:
      containers:
      - name: <your-container-name>
        image: <the-image-from-dockerhub>
      imagePullSecrets:
      - name: regcred # Or whatever you decided to name your secret from step 2
  5. Congratulations, now you’re authenticated to DockerHub

Alternatively, you can also do it via helm (upstream docs):

  1. Have your credentials defined in your values.yaml:

    imageCredentials:
      registry: index.docker.io/v1/
      username: someone
      password: sillyness
      email: someone@host.com
  2. Define our helper template as follows:

    {{- define "imagePullSecret" }}
    {{- with .Values.imageCredentials }}
    {{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }}
    {{- end }}
    {{- end }}
  3. Use the helper template in a larger template to create the Secret manifest:

    apiVersion: v1
    kind: Secret
    metadata:
      name: regcred
    type: kubernetes.io/dockerconfigjson
    data:
      .dockerconfigjson: {{ template "imagePullSecret" . }}
  4. Follow step 4 in the instructions above, to ensure your workload is using this imagePullSecret

For platform-managed images, Skyscrapers offers an ECR Pull-Through Cache which mitigates Docker Hub rate limits at the platform level: system component images are pulled from upstream once and served from your own ECR thereafter. Customers can opt-in by enabling Docker Hub credentials. See the setup guide for details. The cache also covers the workloads listed there, so for your own application images you can either reference the same ECR cache directly or stick with imagePullSecrets as described above.

Last updated on