Skip to content

Commit ce78ff7

Browse files
ci: pull the Temporal Conformance service images from mirror.gcr.io, off Docker Hub's anonymous pull quota (#22545)
Fixes #22541 Clause-②: no ## What The required `Temporal Conformance (live PG + MySQL)` job now pulls its two service images from `mirror.gcr.io`, Google's cache of Docker Hub, instead of from Docker Hub anonymously: - `postgres:16` becomes `mirror.gcr.io/library/postgres:16` - `mysql:8.0` becomes `mirror.gcr.io/library/mysql:8.0` The diff is two `image:` values plus a six-line comment, all in `.github/workflows/ci.yml`. The job name, `env`, `ports` and both health checks (`pg_isready -U postgres`, `mysqladmin ping -h 127.0.0.1`) are unchanged. `scripts/check-required-contexts.mjs` pins the job name, and that name is untouched. ## Why Since 20:53Z on 2026-10-09, every run of this job failed at `Initialize containers` (three `Docker pull failed with exit code 1`, then failure), before checkout or any test body ran. Docker Hub answered `toomanyrequests` for the anonymous per-IP quota. The job is a required context, so the merge queue ejected every entry. The newest failures, read through the jobs API at 21:31Z, are the same: jobs `114034494503` (21:30:40Z), `114033905117`, `114031741661`, `114030793729`, `114029405989` and `114028399482`. Each has `Initialize containers` as its only failing step. A Docker Hub login is not the fix. It needs a maintainer-held secret, and secrets never reach fork pull requests, so those runs would stay on the anonymous quota. ## Measured: same image, same tag, same digest Anonymous registry probe from this session at 2026-10-09T21:32:53Z, `HEAD /v2/REPO/manifests/TAG` with each registry's anonymous token flow, accepting the OCI index and Docker manifest-list types: | image | Docker Hub | mirror.gcr.io | ECR Public (`public.ecr.aws/docker/library`) | |:---|:---|:---|:---| | `postgres:16` | `sha256:ca0bd484cb98bf4b24eb1010e73fb3fcbd6714d240fbc1a10eea5b7dbecb641d` | 200, same digest | 200, same digest | | `mysql:8.0` | `sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b` | 200, same digest | 200, same digest | - The registry probe to Docker Hub itself answered **429** for both repositories, even for `HEAD`, with `ratelimit-limit: 100;w=3600`, `ratelimit-remaining: 0;w=3600` and a `docker-ratelimit-source` naming the egress IP. That is the anonymous per-IP quota this PR moves off. So the Docker Hub column was read from the Hub tag API (`hub.docker.com/v2/repositories/library/IMAGE/tags/TAG`, HTTP 200). It gives `postgres:16` last pushed 2026-10-07T19:07:56Z and `mysql:8.0` last pushed 2026-05-05T02:02:21Z. - Both mirrors returned an OCI image index (`application/vnd.oci.image.index.v1+json`), and neither response carried a rate-limit header. - Why `mirror.gcr.io` and not ECR Public: both serve both tags anonymously with identical digests. `mirror.gcr.io` is a cache of Docker Hub itself, so the bytes are Docker Hub's. ECR Public stays the measured fallback: if this mirror ever misbehaves, the swap is the same two lines to `public.ecr.aws/docker/library/...`. ## Proof There is no Docker daemon in the authoring container, so this PR's own CI run is the measurement. The `Temporal Conformance (live PG + MySQL)` job on this PR must pass `Initialize containers` with the mirror named in its pull lines, then run its suites. The job id and conclusion go in the dispatch report on #22541. ## Acceptance notes - `Scaffold E2E` (`.github/workflows/scaffold-e2e.yml`, on `pull_request`) builds `docker/Dockerfile`, which is `FROM node:22-slim`, and so also pulls from Docker Hub anonymously. It is not one of the seven required contexts, so it does not block the queue, and this PR does not change it. No other required job pulls a container image. - No changeset: a CI-only path publishes nothing. --- _Generated by [Claude Code](https://claude.ai/code/session_01VZqqwTj2wsihZEbfT6yyYN)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent faf6348 commit ce78ff7

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,9 +1521,15 @@ jobs:
15211521
permissions:
15221522
contents: read
15231523

1524+
# Both service images are pulled from mirror.gcr.io, Google's cache of
1525+
# Docker Hub: the same official image, tag and index digest. Pulled from
1526+
# Docker Hub directly they ride its anonymous per-IP quota, which shared
1527+
# runner IPs exhaust, and `Initialize containers` then fails before any
1528+
# step runs. A Docker Hub login is no fix: secrets never reach fork PRs
1529+
# (#22541).
15241530
services:
15251531
postgres:
1526-
image: postgres:16
1532+
image: mirror.gcr.io/library/postgres:16
15271533
env:
15281534
POSTGRES_PASSWORD: postgres
15291535
ports:
@@ -1539,7 +1545,7 @@ jobs:
15391545
# the other half of the compatibility claim. `-h 127.0.0.1` forces the
15401546
# ping over TCP: the image's init phase runs mysqld with networking
15411547
# disabled, so a socket ping would report healthy before init finishes.
1542-
image: mysql:8.0
1548+
image: mirror.gcr.io/library/mysql:8.0
15431549
env:
15441550
MYSQL_ROOT_PASSWORD: root
15451551
MYSQL_DATABASE: conformance

0 commit comments

Comments
 (0)