Files
bot-bottle/docs/image-build-inputs.md
T
didericis-codex 8a4d1714ac
lint / lint (push) Successful in 1m1s
prd-number-check / require-numbered-prds (pull_request) Successful in 6s
tracker-policy-pr / check-pr (pull_request) Successful in 9s
refresh-image-locks / refresh (push) Failing after 2m6s
test / unit (pull_request) Failing after 45s
test / image-input-builds (pull_request) Failing after 52s
test / integration-docker (pull_request) Failing after 1m15s
test / coverage (pull_request) Has been skipped
ci: make image input refreshes deterministic
2026-07-26 09:34:21 +00:00

2.9 KiB

Container image build inputs

Bot-bottle's supported images are intended to rebuild from the same declared inputs on Linux amd64 and arm64. The repository enforces four layers of immutability:

  • Python and Node base images use version-qualified tags plus multi-platform OCI index digests.
  • Debian packages resolve from the same dated snapshot.debian.org archive in every image that runs apt-get install.
  • Gateway Python dependencies install from requirements.gateway.lock with pip --require-hashes; provider npm packages install with npm ci from committed lockfiles.
  • The Codex standalone installer is fetched from the selected Codex release tag, checked against install.sh.sha256, invoked with an exact --release, and then verifies the selected release archive against upstream metadata. The standalone layout is retained because Codex remote control requires it.

Dockerfile.orchestrator.fc is the one intentionally dynamic FROM. It has no default value: the Firecracker build coordinator builds the orchestrator first, resolves its local sha256: image ID, and supplies that exact ID as ORCHESTRATOR_BASE_IMAGE.

Refreshing inputs

Make refreshes on a feature branch and review them like an application dependency update:

  1. For a Python or Node base update, select a version-qualified tag and record its multi-platform index digest in every Dockerfile that shares the base. Confirm the index still contains linux/amd64 and linux/arm64.
  2. For Debian packages, advance DEBIAN_SNAPSHOT to one fixed UTC timestamp in every Dockerfile that uses apt. Do not use the moving Debian mirrors.
  3. Change direct Python versions in requirements.gateway.in, direct npm versions in the provider's package.json, or CODEX_VERSION in the Codex Dockerfile. Direct versions must be exact—no ranges, dist-tags, or unversioned package names.
  4. Push the feature branch or manually run the refresh-image-locks workflow. It regenerates the four derived files with the image's exact Python and Node versions and uploads them as the image-input-locks artifact. It never writes to the branch, so a refresh cannot race with developer pushes.
  5. Download the artifact, replace the four committed files, review the lock diff, and let both normal CI and image-input-builds pass. The latter checks both base architectures, builds every supported image, exercises the exact local Firecracker base-ID handoff, and runs each provider CLI's version smoke test.

Run the fast policy check locally at any point:

python3 scripts/check_image_inputs.py

The check rejects mutable or latest bases, moving apt repositories, network-to-shell installers, unlocked npm/Pi installs, non-exact direct dependencies, missing npm integrity values, and unhashed gateway Python requirements.

Image signing and attestation are tracked separately in issue #339; this policy covers deterministic and integrity-checked build inputs.