Container Registry Pull Reachability and Rate-Budget Ledger avatar

Container Registry Pull Reachability and Rate-Budget Ledger

Pricing

from $20.00 / 1,000 reachability run starts

Go to Apify Store
Container Registry Pull Reachability and Rate-Budget Ledger

Container Registry Pull Reachability and Rate-Budget Ledger

Pulls the manifest of every pinned image reference over HTTPS and reports whether the pull works now, why it would fail, which platforms the manifest holds, the TLS name-match verdict, and how much anonymous rate budget the registry has left. HTTP only, n

Pricing

from $20.00 / 1,000 reachability run starts

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Your build pulls the same images every time. When one pull stops to work, every build stops. You look at your own code first, then at the runner, and only at the end at the registry. That search costs an hour.

This Actor holds the registry answer before you need it. It pulls the manifest of every pinned reference over HTTPS and tells you three things:

  1. Would the pull work now? Yes, or the exact reason for no.
  2. What changed since the last run? The ledger holds the previous status and the previous digest of each reference.
  3. How much pull budget is left? The Actor reads the RateLimit-Limit and RateLimit-Remaining headers of each registry host.

HTTP and TLS only. No browser. No proxy. No database. No container runtime.

What it does for each reference

The Actor walks the same path as a container runtime.

StepCallWhat it records
1GET /v2/<repository>/manifests/<reference>The challenge, or the answer at once.
2The token endpoint of the challengeIs the token endpoint reachable?
3The manifest call again, with the tokenStatus, digest, media type, rate budget.
4The manifest bodyThe platform list of the image index.

The Actor follows each redirect by hand. It records the host chain, and it removes the Authorization header as soon as the host or the port changes, so a token never reaches a content delivery network. A redirect to a scheme other than HTTPS stops the probe with an unreachable verdict, because a cleartext hop would show the token, or your registry password, to every device on the path.

A blocked pull gets more work: one more attempt, and a TLS handshake inspection of the host that failed. That inspection answers the question that costs the most time in an incident:

tls: failed to verify certificate: x509: certificate is not valid for any names, but wanted to match docker-images-prod.<hash>.r2.cloudflarestorage.com

The Actor reports the certificate subject, the subject alternative names and one clear verdict: match, mismatch or unknown.

Input

Give the Actor the reference list of your pipeline, or paste your Dockerfile.

{
"imageRefs": ["alpine:3.20", "ghcr.io/org/app:1.4.2"],
"dockerfile": "FROM golang:1.23 AS build\nFROM alpine:3.20\n",
"expectedPlatform": "linux/amd64",
"failOn": ["unreachable", "unauthorized", "tls_name_mismatch"]
}
FieldMeaning
imageRefs1 to 100 references. A reference without a host goes to Docker Hub.
dockerfileOptional. The Actor reads the image of each FROM line.
expectedPlatformOptional, for example linux/amd64.
failOnThe failure classes that make the run verdict fail.
registryToken, registryUsername, registryPasswordOptional credentials for a private repository that you own.
credentialHostsThe hosts that may receive those credentials.
ledgerStoreNameThe named key-value store that holds the ledger.
concurrency, timeoutSeconds, maxRedirects, maxResponseBytesThe bounds of the run.

Every required field has a default, so a run with the empty input {} works.

The Actor reads the Dockerfile carefully. It skips scratch, it skips a FROM line that points at an earlier build stage, and it skips a line that still holds an unexpanded ARG.

Private repositories

Put your token in registryToken, or your user name and password in registryUsername and registryPassword. Then name the host in credentialHosts, for example ["ghcr.io"]. The Actor sends the credentials only to the token endpoint of a named host. An empty credentialHosts list sends them to every host in your reference list, so fill the list in when the list mixes a private registry with public ones.

Failure classes

ClassMeaning
okThe pull works now.
unreachableThe registry or the token endpoint does not answer.
unauthorizedThe registry refuses the credentials.
rate_limitedThe registry answered 429, or it reports no pull budget left.
not_foundThe repository or the tag does not exist.
server_errorThe registry answers 5xx.
tls_name_mismatchThe certificate is valid, but not for the host that was asked.
tls_errorAnother TLS or certificate chain fault.
platform_missingThe manifest list does not hold expectedPlatform.
invalid_referenceThe text is not a reference, or it points at a private address.

A registry that answers a status with no better class gets unreachable, and the detail field names the status.

Output

Three record types go to the dataset.

Record typeCountHolds
referenceOne for each referenceHost, repository, status, digest, media type, platforms, redirect chain, TLS verdict, response time, failure class, and the change since the last run.
rate-budgetOne for each registry hostRateLimit-Limit, RateLimit-Remaining, the time to reset, and the use since the last run.
run-summaryOneThe pass or fail verdict against failOn, the counts, and the list of references that changed.

The verdict never fails the run

A blocked pull is the answer that you paid for. The Actor writes the verdict into the run-summary record and into the run status message, and the Apify run ends SUCCEEDED. A FAILED run means a malfunction of the Actor, nothing else. Read verdict in the summary record, or read the status message, to gate your pipeline.

The ledger

The Actor keeps one record for each reference and a short rate-budget history for each host in a named key-value store. Every run with the same ledgerStoreName compares against the same ledger. This gives you the sentence that a single run cannot give:

This reference became "tls_name_mismatch" since the last run.

The first run writes the ledger and reports the current status only.

How to use it

  1. Put your pipeline reference list into imageRefs.
  2. Add an Apify schedule. One run each hour is the usual cadence. You can also start the Actor before each deployment.
  3. Read verdict of the run-summary record, or read the status message.

Pricing

The Actor uses pay per event.

EventUnitPriceWhen
reachability-run-startrun0.02Once for each run, after the input is read.
image-ref-probedimage reference probed0.006Once for each reference that the Actor called a registry for.
blocked-pull-diagnosedblocked reference0.02Once for each reference that stays blocked after the second attempt and the TLS trace.

Two references are not charged as a probe: a reference that cannot be parsed, and a reference that points at a private or reserved address. The Actor makes no call for them. A reference that fails once and works on the second attempt is not charged as a diagnosis, because you receive a working pull.

The default cap maxTotalChargeUsd is 8.00 for one run. A run over 100 references costs at most 0.02 + 0.60 + 2.00 = 2.62, so the cap holds the worst case, when a whole registry is down and every reference takes the expensive path.

What one month costs

20 healthy references, one run each hour, 30 days:

EventCountPriceCost
reachability-run-start24 runs x 30 days = 7200.0214.40
image-ref-probed20 refs x 24 runs x 30 days = 144000.00686.40
blocked-pull-diagnosed0 blocked = 00.020.00
Total100.80

The cadence drives the bill, not the reference count alone. Select the schedule that your pipeline needs:

ScheduleRuns each day20 referencesFor each reference
Every hour24100.805.04
Every 6 hours416.800.84
Once each day14.200.21

A blocked reference adds 0.02 for each run while it stays blocked.

Limits and rules

  • The Actor refuses loopback, private, link-local and reserved addresses, for the registry host and for every redirect hop.
  • Only HTTPS, for the first call and for every redirect hop. A reference carries no URL scheme.
  • 1 to 100 references for each run.
  • The Actor reads at most maxResponseBytes from one answer.
  • The Actor does not download image layers. It reads the manifest, and it reads the image config blob only when you set expectedPlatform and the reference resolves to a single-platform manifest.

Develop

uv sync
uv run pytest
uv run ruff check .