Skip to content

Commit eefbc9a

Browse files
committed
chore(build): pin base Docker images
1 parent fd8ef92 commit eefbc9a

5 files changed

Lines changed: 85 additions & 6 deletions

File tree

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM rust:1.93-slim-trixie AS builder
1+
FROM rust:1.93-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956 AS builder
22
WORKDIR /app
33

44
ARG TARGETARCH
@@ -20,7 +20,7 @@ RUN --mount=type=cache,target=/app/target cargo build --release && \
2020
upx --best --lzma ./retrack
2121

2222
# Check out https://gcr.io/distroless/cc-debian13:nonroot
23-
FROM gcr.io/distroless/cc-debian13:nonroot
23+
FROM gcr.io/distroless/cc-debian13:nonroot@sha256:9c4fe2381c2e6d53c4cfdefeff6edbd2a67ec7713e2c3ca6653806cbdbf27a1e
2424
EXPOSE 7676
2525

2626
WORKDIR /app

Dockerfile.web-scraper

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM --platform=$BUILDPLATFORM node:22-slim AS builder
1+
FROM --platform=$BUILDPLATFORM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea AS builder
22
WORKDIR /app
33

44
# Copy workspace root `package.json` and `package-lock.json` files,
@@ -12,7 +12,7 @@ COPY ["./components/retrack-web-scraper", "./components/retrack-web-scraper"]
1212
RUN set -x && npm test --ws
1313
RUN set -x && npm run build --ws
1414

15-
FROM node:22-slim
15+
FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea
1616
ENV NODE_ENV=production \
1717
PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
1818
RETRACK_WEB_SCRAPER_BROWSER_CHROMIUM_EXECUTABLE_PATH=/usr/local/bin/chromium

Dockerfile.web-scraper-camoufox

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.14-slim-trixie
1+
FROM python:3.14-slim-trixie@sha256:fb83750094b46fd6b8adaa80f66e2302ecbe45d513f6cece637a841e1025b4ca
22
EXPOSE 7777
33

44
ENV CAMOUFOX_PORT=7777

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ COMPOSE_DB := dev/docker/docker-compose.yml
22
ENV_FILE := .env
33
CHROME_PATH ?= /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
44

5-
.PHONY: dev-up dev-down api scraper-setup scraper scraper-debug db-reset db-migrate test test-api test-scraper fmt clippy check docker-api docker-scraper docker-scraper-camoufox clean help
5+
.PHONY: dev-up dev-down api scraper-setup scraper scraper-debug db-reset db-migrate test test-api test-scraper fmt clippy check docker-api docker-scraper docker-scraper-camoufox docker-pin-digests clean help
66

77
## ---------- Development ----------
88

@@ -79,6 +79,9 @@ docker-scraper: ## Build the Web Scraper (Chromium) Docker image.
7979
docker-scraper-camoufox: ## Build the Web Scraper (Camoufox/Firefox) Docker image.
8080
docker build --tag retrack-web-scraper-camoufox:latest -f Dockerfile.web-scraper-camoufox .
8181

82+
docker-pin-digests: ## Re-pin base images in Dockerfiles to current SHA256 digests.
83+
./dev/scripts/docker-pin-digests.sh
84+
8285
## ---------- Misc ----------
8386

8487
clean: ## Remove build artifacts.

dev/scripts/docker-pin-digests.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Re-pin base images in Retrack Dockerfiles to their current SHA256 manifest-list digests.
4+
# Usage: ./dev/scripts/docker-pin-digests.sh
5+
#
6+
set -euo pipefail
7+
8+
RETRACK_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
9+
10+
DOCKERFILES=(
11+
"$RETRACK_ROOT/Dockerfile"
12+
"$RETRACK_ROOT/Dockerfile.web-scraper"
13+
"$RETRACK_ROOT/Dockerfile.web-scraper-camoufox"
14+
)
15+
16+
# File-based cache so subshells can share resolved digests.
17+
CACHE_FILE="$(mktemp)"
18+
trap 'rm -f "$CACHE_FILE"' EXIT
19+
20+
get_digest() {
21+
local image="$1"
22+
23+
# Check cache.
24+
local cached
25+
cached="$(grep -F "$image " "$CACHE_FILE" 2>/dev/null | head -1 | awk '{print $2}')" || true
26+
if [[ -n "$cached" ]]; then
27+
echo "$cached"
28+
return
29+
fi
30+
31+
echo " Fetching digest for $image ..." >&2
32+
local digest
33+
digest="$(docker buildx imagetools inspect "$image" 2>/dev/null \
34+
| grep -m1 '^Digest:' | awk '{print $2}')"
35+
36+
if [[ -z "$digest" || ! "$digest" =~ ^sha256: ]]; then
37+
echo "ERROR: failed to fetch digest for $image" >&2
38+
return 1
39+
fi
40+
41+
# Strip the sha256: prefix we add it back when rewriting.
42+
digest="${digest#sha256:}"
43+
echo "$image $digest" >> "$CACHE_FILE"
44+
echo "$digest"
45+
}
46+
47+
for dockerfile in "${DOCKERFILES[@]}"; do
48+
[[ -f "$dockerfile" ]] || { echo "SKIP: $dockerfile not found"; continue; }
49+
50+
tmp="$(mktemp)"
51+
changed=false
52+
53+
while IFS= read -r line; do
54+
if [[ "$line" =~ ^FROM[[:space:]] ]]; then
55+
# Strip any existing @sha256:... from the image reference.
56+
stripped="$(echo "$line" | sed -E 's/@sha256:[0-9a-f]+//')"
57+
58+
# Extract the image:tag - it's the token after FROM (and optional --platform=...).
59+
image_tag="$(echo "$stripped" | sed -E 's/^FROM[[:space:]]+(--platform=[^ ]+[[:space:]]+)?([^ ]+).*/\2/')"
60+
61+
digest="$(get_digest "$image_tag")"
62+
# Insert @sha256:digest right after the image:tag in the stripped line.
63+
line="$(echo "$stripped" | sed -E "s|${image_tag}|${image_tag}@sha256:${digest}|")"
64+
changed=true
65+
fi
66+
echo "$line"
67+
done < "$dockerfile" > "$tmp"
68+
69+
if $changed; then
70+
mv "$tmp" "$dockerfile"
71+
echo "Pinned: $dockerfile"
72+
else
73+
rm "$tmp"
74+
echo "SKIP: no FROM lines in $dockerfile"
75+
fi
76+
done

0 commit comments

Comments
 (0)