Repository navigation
Address PR #1500 review follow-ups for slim production image - #1524
Conversation
Six review observations on the slim-production-image PR are addressed without altering deployed runtime semantics: - Pin Python to 3.11.15-slim-bookworm in both Dockerfiles so rebuilds on different dates do not silently pick up a new CPython point release. - Mirror local's pinned-URL spaCy install in production: download en_core_web_sm/lg via wget into the build-stage wheel cache, install via the existing pip --no-index step, and replace the runtime `spacy download` calls with a `spacy.load(...)` smoke test. wget stays out of the runtime image. - Split the release workflow's Django path into build+load -> size budget gate -> docker push, removing the load+push co-existence in a single build-push-action step. Non-Django images keep the original combined path. - Document why locale/ is safely excluded from the build context (no .po/.mo files exist, no startup script invokes compilemessages) and clarify gettext's role in the runtime apt comment. - Document the brotli >=1.1.0 floor rationale in requirements/base.txt so the constraint is no longer ambiguous. - Verify ffmpeg has zero remaining consumers across the codebase. Closes #1505
Code Review — PR #1524 (Docker image hardening follow-ups)Overall this is a clean, well-documented set of housekeeping changes that address all six items from the prior review without touching runtime semantics. The comments throughout are unusually good — they explain why, not just what. A few issues worth addressing before merge: Issues1.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…-4pM9m # Conflicts: # CHANGELOG.md
…te intact - Add sha256sum -c verification after each spaCy model wheel download in both compose/production/django/Dockerfile and compose/local/django/Dockerfile. Pinning to an explicit GitHub release URL reduces drift risk but without a hash check the build is still vulnerable to a modified release or CDN MITM; sha256sum -c fails the build immediately on mismatch. - Confirm the size-budget gate is intact: the Enforce Django image size budget step uses steps.meta.outputs.tags (not the removed steps.build.outputs.imageid) to identify the locally-loaded image for docker image inspect, so the split build path is correct as-is. - Fix post-merge mypy regression: get_embedder / aget_embedder return type is tuple[Optional[type[BaseEmbedder]], Optional[str]] but get_component_by_name returns type[PipelineComponentBase]; cast() at the return site bridges the gap without changing runtime behaviour. - Update CHANGELOG.md to document the SHA-256 addition and size-gate verification; also re-add the Docker hardening entry that was lost during the merge conflict resolution. Closes #1524
Code Review: PR #1524 — Slim-image follow-upsOverall this is a well-scoped, well-documented cleanup PR. Every change addresses a concrete observation from PR #1500 and the rationale is clearly recorded. A few items worth flagging: Security: SHA-256 hash provenanceThe new SHA-256 checks are the right call — pinning a URL alone is insufficient against a retroactive release modification. However, neither the PR description nor the Dockerfiles document where these hashes were sourced (e.g., the release page checksum file, a local # Hashes verified against the upstream release on 2026-05-05:
# https://github.com/explosion/spacy-models/releases/tag/en_core_web_sm-3.8.0There's also a subtle discrepancy worth double-checking: the Please verify the raw file character count — SHA-256 must be exactly 64 hex chars. If it's truly 63, the Workflow: size-budget gate reference after
|
Signed-off-by: JSIV <5049984+JSv4@users.noreply.github.com>
Code Review — PR #1524 (Docker image hardening follow-ups)
OverviewThis is a clean, focused follow-up to PR #1500. It addresses six review observations about the slim production image without changing any deployed runtime semantics. All changes are infrastructure/DevOps (Dockerfiles, CI workflow, comments, and changelog). Positives
Issues & Suggestions1. SHA-256 hashes — no provenance trail in the PR (minor)The checksums for 2.
|
| Area | Assessment |
|---|---|
| Correctness | ✅ All changes are safe and correct |
| Security | ✅ Supply-chain improvement (SHA-256); minor workflow injection surface (informational only) |
| Reproducibility | ✅ Python pin + spaCy pin + hash check all improve build determinism |
| Documentation | ✅ Comments explain the why; provenance of hashes could be noted |
| Test coverage | ✅ Backend test suite unaffected; hash rejection path untested (low priority) |
Overall this is a solid hardening PR. The issues noted above are minor and informational — nothing here warrants a re-review or follow-up PR unless the team wants to add the hash provenance comment.
Summary
Closes #1505. Addresses all six review observations on PR #1500 (the slim-production-image change) without altering deployed runtime semantics.
locale/excluded from build context — does anything needcompilemessages?locale/contains onlyREADME.rst(no.po/.mo), andgrep -r compilemessagesacross*.py,*.sh,Dockerfile*,*.yml/yamlfinds zero invocations. Documented why exclusion is safe in.dockerignoreand clarifiedgettext's role as a build hook in the runtime apt comment.load: true+push: trueco-existence in release workflowdocker push <tag>per tag. Non-Django images keep the original combinedpush: true, load: falsepath.ffmpegremoval — verify no other consumersgrep -r "ffmpeg"acrossopencontractserver/,compose/,config/,frontend/, and the workflow tree returns nothing. No code change required; verification recorded in CHANGELOG.en_core_web_sm-3.8.0anden_core_web_lg-3.8.0wheels in the build stage with the samewgetretry semantics ascompose/local/django/Dockerfile, into the existing/usr/src/app/wheelscache. The runtime stage installs them via the existingpip install --no-index --find-links=/wheels/ /wheels/*step (no per-package change) and runs aspacy.load(...)smoke test.wgetis added to the build stage only — never reaches the runtime image.3.11.15-slim-bookwormin bothcompose/production/django/Dockerfileandcompose/local/django/Dockerfile(verified available on Docker Hub). Rebuilds on different dates can no longer silently pick up a new CPython point release.brotli>=1.1.0floor rationalerequirements/base.txt. 1.1.0 is the current major-version line under active upstream maintenance; the underlying_brotliC-extension API thathttpxdepends on has been stable since 1.0.x, so the floor can be lowered safely if a transitive constraint demands it.Files changed
.dockerignore— comment block above thelocale/line documenting why exclusion is safe..github/workflows/docker-build-release.yml— split Django path into build+load / push steps; non-Django path unchanged.CHANGELOG.md— newChangedentry under[Unreleased]listing all six items.compose/production/django/Dockerfile— pin Python, addwgetto build stage, fetch pinned spaCy wheels, replace runtimespacy downloadwith aspacy.load(...)smoke test, clarifygettextruntime comment.compose/local/django/Dockerfile— pin Python (kept in sync with production).requirements/base.txt— extend thebrotli>=1.1.0comment with explicit rationale.Test plan
docker compose -f production.yml build djangobuilds againstpython:3.11.15-slim-bookwormend-to-end and the spaCyspacy.load(...)smoke test passes.docker compose -f local.yml build djangostill builds (Python pin is the only change here).load: true, the size-budget gate running against the loaded image, thendocker pushsucceeding for each tag.Generated by Claude Code