Skip to content

docker: Add HEADS_FORCE_DOCKER_REBUILD and improve reproducibility checks#2081

Merged
tlaurion merged 1 commit intolinuxboot:masterfrom
tlaurion:docker_scripts_improvements-local_dev_reconstruct_from_nix
Apr 16, 2026
Merged

docker: Add HEADS_FORCE_DOCKER_REBUILD and improve reproducibility checks#2081
tlaurion merged 1 commit intolinuxboot:masterfrom
tlaurion:docker_scripts_improvements-local_dev_reconstruct_from_nix

Conversation

@tlaurion
Copy link
Copy Markdown
Collaborator

@tlaurion tlaurion commented Apr 8, 2026

What

  • Add HEADS_FORCE_DOCKER_REBUILD=1 to force rebuild from flake.nix/flake.lock regardless of git status; also deletes the cached nix store result/link before rebuilding
  • Add --print-build-logs to nix build for build visibility
  • Use docker load -i result instead of docker load < result
  • Use script-relative --out-link path so nix build and docker load are deterministic regardless of $PWD
  • Improve reproducibility check: compare config digests (authoritative, bit-for-bit) rather than manifest digests; explain why they differ
  • Show which fetch method was used (registry+jq, registry+sed, skopeo+jq, or pulled)
  • Add get_remote_manifest_digest() to show the Docker Hub URL for manual cross-check
  • Fall back gracefully to docker pull when registry API is unavailable; tip to install jq/curl to avoid the pull
  • Update doc/docker.md explaining config vs manifest digests, with accurate example output
  • Normalize indentation to tabs across all docker scripts

Correctness fixes (addressed during Copilot review)

  • result_target declared local in the HEADS_FORCE_DOCKER_REBUILD path
  • Dangling result symlink always removed (not only when target exists)
  • get_local_manifest_digest() removed (unused, would have hashed with wrong newline semantics)
  • sha256 regex restricted to exactly 64 hex chars ({64})
  • (via ${remote_method}) reflects actual fetch path instead of hardcoded "Verified via registry API"
  • Docker Hub URL uses sha256-<hex> path format (not sha256:<hex>)
  • curl availability checked before registry API path; non-Docker-Hub registries short-circuit early
  • curl -D - -o /dev/null captures only headers, not the full manifest body
  • _parse_docker_image() normalises docker.io/index.docker.io to registry-1.docker.io and adds library/ prefix for official images
  • === End Reproducibility Check === only printed at actual return points, not before the pull fallback
  • last_segment declared local to avoid leaking into calling scope
  • pin-and-run.sh: strip :tag before appending @digest to produce valid Docker reference (repo@sha256:...)

Example: force rebuild

HEADS_FORCE_DOCKER_REBUILD=1 ./docker_local_dev.sh
Developer helper: ./docker_local_dev.sh (local image: linuxboot/heads:dev-env)
Rebuilds local image when flake.nix/flake.lock have uncommitted changes. Opt-out: HEADS_SKIP_DOCKER_REBUILD=1
Force rebuild: HEADS_FORCE_DOCKER_REBUILD=1
For published images use: ./docker_latest.sh; for reproducible builds use: ./docker_repro.sh

HEADS_FORCE_DOCKER_REBUILD=1: forcing Docker rebuild from flake
Verifying Nix environment...
Building Docker image from flake.nix...
[...]
Loading Docker image...
Loaded image: linuxboot/heads:dev-env
Using local dev image: linuxboot/heads:dev-env

Example: reproducibility check

HEADS_CHECK_REPRODUCIBILITY=1 ./docker_local_dev.sh

Git repository is clean. Using existing Docker image.
Using local dev image: linuxboot/heads:dev-env

=== Reproducibility Check ===
Local image (linuxboot/heads:dev-env):   sha256:8ae7744cc8b4ff0e959aa6dfeeb40dbd40d20ac6fa1f7071dd21ec0c2d0f9f41
Remote image (tlaurion/heads-dev-env:latest): sha256:8ae7744cc8b4ff0e959aa6dfeeb40dbd40d20ac6fa1f7071dd21ec0c2d0f9f41
(via registry+jq)
✓ MATCH: Config digests identical (bit-for-bit reproducible)
Config digest: sha256:8ae7744cc8b4ff0e959aa6dfeeb40dbd40d20ac6fa1f7071dd21ec0c2d0f9f41
Note: manifest digest differs from config (normal - manifest includes metadata)
Docker Hub: https://hub.docker.com/layers/tlaurion/heads-dev-env/latest/images/sha256-5f890f3d1b6b57f9e567191695df003a2ee880f084f5dfe7a5633e3e8f937479
=== End Reproducibility Check ===

Copilot AI review requested due to automatic review settings April 8, 2026 18:49
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 8f2510a to 8ee7c58 Compare April 8, 2026 18:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a forced rebuild option to the Docker/Nix developer workflow and refines the reproducibility check to be more transparent about which digests are being compared and how they were obtained.

Changes:

  • Introduces HEADS_FORCE_DOCKER_REBUILD=1 to rebuild from flake.nix/flake.lock regardless of git status (and attempts to clear cached build outputs).
  • Improves Nix build visibility (--print-build-logs) and refactors reproducibility-check messaging / helper functions.
  • Updates Docker documentation to explain config digest vs manifest digest and updates example output.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docker/common.sh Adds forced rebuild behavior, changes nix build/load invocation, and extends reproducibility-check helpers/output.
docker_local_dev.sh Documents/exposes HEADS_FORCE_DOCKER_REBUILD and keeps dev wrapper aligned with common.sh.
docker_latest.sh Indentation normalization; continues to rely on shared helpers.
docker_repro.sh Indentation normalization; continues to enforce digest-pinned images.
doc/docker.md Documents the new env var and expands digest/reproducibility explanations and example output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
Comment thread doc/docker.md Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch 2 times, most recently from 7af1497 to d1ba3c4 Compare April 8, 2026 19:13
@tlaurion tlaurion requested a review from Copilot April 8, 2026 19:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread doc/docker.md Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch 2 times, most recently from cb2beb7 to 0d9c44f Compare April 8, 2026 19:23
@tlaurion tlaurion requested a review from Copilot April 8, 2026 19:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread doc/docker.md
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch 2 times, most recently from 6a7b71f to b7a7409 Compare April 8, 2026 19:34
@tlaurion tlaurion requested a review from Copilot April 8, 2026 19:34
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from b7a7409 to b9854e5 Compare April 8, 2026 19:46
@tlaurion tlaurion requested a review from Copilot April 8, 2026 19:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from b9854e5 to 0afb709 Compare April 8, 2026 21:39
@tlaurion tlaurion requested a review from Copilot April 8, 2026 21:40
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 0afb709 to bf27183 Compare April 8, 2026 21:54
@tlaurion tlaurion requested a review from Copilot April 8, 2026 21:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread doc/docker.md Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch 2 times, most recently from 75ce0c3 to 100082e Compare April 9, 2026 14:43
@tlaurion tlaurion requested a review from Copilot April 9, 2026 14:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
Comment thread doc/docker.md Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 100082e to 08fe3e8 Compare April 9, 2026 14:55
@tlaurion tlaurion requested a review from Copilot April 9, 2026 15:10
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 08fe3e8 to 1a56cf1 Compare April 9, 2026 15:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 1a56cf1 to 773633d Compare April 9, 2026 15:18
@tlaurion tlaurion requested a review from Copilot April 9, 2026 15:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh
Comment thread docker/pin-and-run.sh Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 773633d to 72372c1 Compare April 9, 2026 15:30
@tlaurion tlaurion requested a review from Copilot April 9, 2026 15:34
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread doc/docker.md Outdated
@tlaurion tlaurion force-pushed the docker_scripts_improvements-local_dev_reconstruct_from_nix branch from 72372c1 to 9fc8dc5 Compare April 9, 2026 15:40
@tlaurion tlaurion requested a review from Copilot April 9, 2026 15:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/pin-and-run.sh Outdated
Comment thread docker/common.sh Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh Outdated
Comment thread docker/common.sh Outdated
Comment thread docker/common.sh
Comment thread docker/get_digest.sh Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

docker/pin-and-run.sh:135

  • print_digest_info is given ${image%@*}@${digest}, which will include the original :tag (e.g., repo:v0.2.7@sha256:...). That combined tag+digest form is not a valid Docker reference and may confuse users copying the “Image:” line. Consider normalizing to repo@sha256:... by stripping any tag (from the last path component) before appending the digest.

print_digest_info "${image%@*}@${digest}" "${digest}" "user" "${envvar}"
echo "Running ${wrapper} pinned to ${digest} (exporting ${envvar})" >&2

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/get_digest.sh
Comment thread docker/get_digest.sh
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/common.sh
Comment thread docker/common.sh
…ecks

- Add HEADS_FORCE_DOCKER_REBUILD=1 to force rebuild from flake.nix/flake.lock
- Delete cached nix store result when forcing rebuild
- Add --print-build-logs to nix build for visibility
- Use docker load -i instead of docker load < for consistency
- Improve reproducibility check: explain config vs manifest digests
- Show method used (registry+jq, registry+sed, or pulled)
- Add tip to install jq and curl for faster registry checks
- Add get_remote_manifest_digest() with correct Docker Hub URL format
- Update doc/docker.md explaining config vs manifest digests
- Normalize indentation to tabs across docker scripts
- Use script-relative paths for deterministic nix build (--out-link)
- Add shared _parse_docker_image helper for consistent registry parsing
- Handle localhost as registry hostname (not Docker Hub)

Fixes:
- local result_target declaration in force rebuild
- handle regular file case for result (not just symlink)
- use printf instead of echo in hash computation
- fall back to shasum when sha256sum unavailable
- ensure temp directory cleanup on all paths
- handle @digest references in get_remote_manifest_digest
- restrict sha256 regex to exactly 64 hex chars
- use remote_method instead of hardcoded message
- Docker Hub URL uses sha256-{digest} not sha256:{digest}
- fix regex in get_remote_config_digest: use \. not \. for dot matching
- remove unused get_local_manifest_digest function
- move End marker to actual end points
- distinguish fetch_failed from mismatch in fallback message
- update documentation mismatch example to match current output
- check curl availability in get_remote_config_digest
- only show Docker Hub URL for Docker Hub images
- add curl availability check to get_remote_manifest_digest
- fix readlink -f fallback to use quoted variable
- fix pin-and-run.sh: strip :tag before appending @digest for valid Docker ref

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 7 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bounty/Donations expected Work could/should be funded by interested stakeholder buildsystem UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants