Skip to content

Commit 70b73d3

Browse files
DAdjadjclaude
andcommitted
Fix update check: use manifest list digest, not platform-specific
Docker stores the manifest list (multi-arch) digest in RepoDigests, not the platform-specific one. Compare like with like. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8d86146 commit 70b73d3

File tree

2 files changed

+7
-31
lines changed

2 files changed

+7
-31
lines changed

app/sync.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -331,33 +331,22 @@ def run():
331331

332332
def _check_for_update():
333333
"""Check Docker Hub for a newer image and store result in DB."""
334-
import subprocess, os, platform, requests as _req
334+
import subprocess, os, requests as _req
335335
if not os.path.exists("/var/run/docker.sock"):
336336
return
337337
repo = "daalves/bridge-bank"
338338
tag = "latest"
339339
token_resp = _req.get(f"https://auth.docker.io/token?service=registry.docker.io&scope=repository:{repo}:pull", timeout=5)
340340
token = token_resp.json().get("token", "")
341-
manifest_resp = _req.get(
341+
manifest_resp = _req.head(
342342
f"https://registry-1.docker.io/v2/{repo}/manifests/{tag}",
343343
headers={
344344
"Authorization": f"Bearer {token}",
345345
"Accept": "application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json",
346346
},
347347
timeout=5
348348
)
349-
remote_digest = ""
350-
manifest_data = manifest_resp.json()
351-
arch = platform.machine()
352-
arch_map = {"x86_64": "amd64", "aarch64": "arm64", "armv7l": "arm"}
353-
target_arch = arch_map.get(arch, arch)
354-
for m in manifest_data.get("manifests", []):
355-
p = m.get("platform", {})
356-
if p.get("architecture") == target_arch and p.get("os") == "linux":
357-
remote_digest = m.get("digest", "")
358-
break
359-
if not remote_digest:
360-
remote_digest = manifest_resp.headers.get("Docker-Content-Digest", "")
349+
remote_digest = manifest_resp.headers.get("Docker-Content-Digest", "")
361350
local_digest = subprocess.run(
362351
["docker", "inspect", "--format", "{{index .RepoDigests 0}}", f"{repo}:{tag}"],
363352
capture_output=True, text=True, timeout=10

app/web/server.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -746,30 +746,17 @@ def update_check():
746746
tag = IMAGE_NAME.split(":")[1] if ":" in IMAGE_NAME else "latest"
747747
token_resp = _req.get(f"https://auth.docker.io/token?service=registry.docker.io&scope=repository:{repo}:pull", timeout=5)
748748
token = token_resp.json().get("token", "")
749-
# Get the manifest list to find the platform-specific digest,
750-
# which matches what docker stores in RepoDigests after a pull.
751-
manifest_resp = _req.get(
749+
# HEAD request for the manifest list digest — this matches what
750+
# docker stores in RepoDigests after pulling a multi-arch image.
751+
manifest_resp = _req.head(
752752
f"https://registry-1.docker.io/v2/{repo}/manifests/{tag}",
753753
headers={
754754
"Authorization": f"Bearer {token}",
755755
"Accept": "application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json",
756756
},
757757
timeout=5
758758
)
759-
remote_digest = ""
760-
manifest_data = manifest_resp.json()
761-
import platform
762-
arch = platform.machine()
763-
arch_map = {"x86_64": "amd64", "aarch64": "arm64", "armv7l": "arm"}
764-
target_arch = arch_map.get(arch, arch)
765-
for m in manifest_data.get("manifests", []):
766-
p = m.get("platform", {})
767-
if p.get("architecture") == target_arch and p.get("os") == "linux":
768-
remote_digest = m.get("digest", "")
769-
break
770-
if not remote_digest:
771-
# Single-arch image, use the digest from the response header
772-
remote_digest = manifest_resp.headers.get("Docker-Content-Digest", "")
759+
remote_digest = manifest_resp.headers.get("Docker-Content-Digest", "")
773760
local_digest = subprocess.run(
774761
["docker", "inspect", "--format", "{{index .RepoDigests 0}}", IMAGE_NAME],
775762
capture_output=True, text=True, timeout=10

0 commit comments

Comments
 (0)