Determining how the Docker Free Tier sunset affects you

How news of the Docker Free Tier being sunset in March 2023 led to organisations wanting to understand their dependence on different namespaces or images on the public Docker Hub.

(Note: adapted from the blog post Working out which Docker namespaces and images you most depend on)

Related read: Case study: Determining the Docker registries, namespaces and images you most depend on.

Context

When Docker announced that Free Team organisations would be sunset in March 2023, there was a good deal of concern from the Software Engineering community, many of whom were unclear how much of an impact this would have on them.

This change had an impact to not only teams running their own Docker hub organisations (also known as "namespaces"), but pulling from other peoples' namespaces, or if anyone outside of their organisation was pulling from their namespace.

For instance, if a well-used namespace, such as goreleaser, did not either apply for a Docker-Sponsored Open Source Project, or pay up, then any downstream users would be impacted by more frequent rate limits or even being unable to pull the images until the next billing cycle.

This introduced considerable risk to companies that didn't a straightforward means to easily query this data, and Docker Inc didn't provide any tooling to work this out for yourself.

Although Docker have since cancelled this change, understanding the usage of Docker images across your organisation can be super helpful, which is expanded upon in Case study: Determining the Docker registries, namespaces and images you most depend on.

Problem

Data

Let's say that we have the following data in the renovate table:

platform organisation repo package_name version current_version package_manager package_file_path datasource dep_types
gitlab technottingham Hack24-API mongo 3.4.3 3.4.3 docker-compose docker-compose.yml docker []
gitlab jamietanna annadodson monachus/hugo gitlabci .gitlab-ci.yml docker ["image"]
github co-cddo api-catalogue ruby 3.3.0-alpine 3.3.0-alpine dockerfile Dockerfile docker ["final"]
github elastic beats busybox docker-compose .ci/jobs/docker-compose.yml docker []
github incident-io catalog-importer alpine 20230329 20230329 dockerfile Dockerfile docker ["final"]
github thechangelog changelog.com ghcr.io/thechangelog/changelog-runtime elixir-v1.14.5-erlang-v26.2-nodejs-v20.10.0 docker-compose .devcontainer/docker-compose.yml docker []
github cloud-custodian cloud-custodian cloudcustodian/c7n latest helm-values tools/ops/azure/container-host/chart/values.yaml docker []
github hashicorp consul docker.mirror.hashicorp.services/alpine 3.18 3.18 dockerfile Dockerfile docker ["stage"]
gitlab jamietanna content-negotiation openjdk 11 11 gitlabci .gitlab-ci.yml docker ["image"]
gitlab jamietanna content-negotiation-go golang 1.18 1.18 gitlabci .gitlab-ci.yml docker ["image"]
gitlab jamietanna cucumber-reporting-plugin openjdk 11 11 gitlabci .gitlab-ci.yml docker ["image"]
github wiremock wiremock-graphql-extension maven 3.6.3-jdk-11-slim 3.6.3-jdk-11-slim dockerfile wiremock-graphql-extension/Dockerfile docker ["stage"]

(Note: this is a subset of the available data)

Query

The dmd CLI has an inbuilt query that produced the following output:

$ dmd report mostPopularDockerImages --db dmd.db
Renovate

(ommitted output for brevity)

+----------------------------------+-----+
| NAMESPACE                        |   # |
+----------------------------------+-----+
| library                          | 499 |
| ghcr.io/gravitational            |  18 |
| dockersamples                    |  12 |
| gcr.io/distroless                |  11 |
| public.ecr.aws/gravitational     |  10 |
| registry1.dsop.io/redhat/ubi     |  10 |
| docker.mirror.hashicorp.services |  10 |
| wiremock                         |   8 |
| docker                           |   8 |
| docker.elastic.co/elasticsearch  |   7 |
| cimg                             |   6 |
| hashicorpdev                     |   6 |
+----------------------------------+-----+

(ommitted output for brevity)

Note that this isn't straightforward to do with an SQL statement on its own.