Skip to content

fix(cloudflare): reuse unchanged container image digests - #1282

Merged
sam-goodwin merged 8 commits into
alchemy-run:mainfrom
danieljvdm:fix/container-digest-reuse
Aug 23, 2026
Merged

fix(cloudflare): reuse unchanged container image digests#1282
sam-goodwin merged 8 commits into
alchemy-run:mainfrom
danieljvdm:fix/container-digest-reuse

Conversation

@danieljvdm

@danieljvdm danieljvdm commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Cloudflare container applications now resolve pushed tags to immutable registry digests and persist both the digest and a fingerprint of the complete desired application configuration.

A changed source hash can still produce the same registry manifest. When that happens, the provider preserves the live image reference and returns before updateContainerApplication when the desired scaling, placement, and runtime configuration fingerprint is also unchanged. A changed image digest or application configuration still follows the normal update and rollout path.

This is the default reconciliation behavior rather than an opt-in: an apply with no effective desired-state change should not create a new application version. Persisting the desired-state fingerprint avoids comparing against Cloudflare-enriched response defaults and ensures that removing a previously configured field is still recognized as a real change. Existing state without the fingerprint migrates conservatively through one normal update.

The digest has a single source: after a push (or for a pre-pushed tag) the provider asks the registry — HEAD /v2/<repo>/manifests/<tag> with the minted pull credentials — rather than scraping docker push output. A reference that already carries @sha256:… is used as-is.

Regression tests

All in ContainerApplication.test.ts, against the real registry and API:

  • identical image re-push — the same remote image under two references changes the source hash but not the manifest; the live image and version must not change, and a genuinely different tag must roll out:

    const first = yield* deployImage(scratch, "mendhak/http-https-echo:41");
    const second = yield* deployImage(scratch, "docker.io/mendhak/http-https-echo:41");
    expect(second.app.configuration.image).toBe(first.app.configuration.image);
    expect(yield* live(accountId, first.app.applicationId)).toMatchObject({
      version: first.app.version,
      image: first.app.configuration.image,
    });

    Without the fix the second deploy swaps the live image to the freshly pushed :<sourceHash> tag and creates a rollout.

  • pre-pushed tag reference — a consumer referencing the pushed <repo>:<sourceHash> tag resolves to the same digest reference as one referencing <repo>@sha256:… (exercises the registry probe directly).

  • legacy state migration — the row is rewritten to a pre-digest shape (hash.image only, live image rolled back onto the tag); the next drift deploy keeps the tag reference, persists the digest + fingerprint through one update, and every later drift is a noop.

  • Durable Object re-create — the live app is replaced out-of-band by a same-name app without the DO attachment (what precreate leaves behind) with a staled source hash; the re-create path rebuilds, matches the digest, and attaches the DO without changing the image reference.

@danieljvdm
danieljvdm marked this pull request as draft August 21, 2026 05:20
@danieljvdm danieljvdm closed this Aug 21, 2026
@danieljvdm danieljvdm reopened this Aug 21, 2026
@danieljvdm
danieljvdm marked this pull request as ready for review August 21, 2026 05:34
@sam-goodwin

Copy link
Copy Markdown
Contributor

Are there any regression tests we can add to exercise this?

sam-goodwin and others added 5 commits August 23, 2026 01:35
…ating a new container version

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e registry manifest probe

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the docker push stdout scrape + PushDigestMissing fallback; the
registry manifest probe is the single digest source for every image
path, so every build test exercises it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e-create digest reuse

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sam-goodwin
sam-goodwin merged commit 49c27be into alchemy-run:main Aug 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants