Improve Docker build reliability and add build idempotency:#64
Improve Docker build reliability and add build idempotency:#64jacobweinstock wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to make local/CI Docker-based workflows more reliable and repeatable by ensuring built images are available locally, reducing unnecessary rebuild work, and introducing a dependency lockfile for reproducible Python resolution.
Changes:
- Add
--loadtodocker buildx buildso built images are available in the local Docker daemon. - Add initramfs-stage idempotency by skipping mkosi initramfs rebuild when an output file already exists (unless
--forceis used). - Add
uv.lockand update the builderDockerfileto precreate a persistent venv intended to be reused byuv run.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
uv.lock |
Introduces a uv lockfile intended to make dependency resolution reproducible. |
captain/docker.py |
Ensures buildx builds load images into the local daemon for subsequent docker run usage. |
captain/cli/_stages.py |
Adds a skip-path to avoid rebuilding initramfs when an existing output is present. |
Dockerfile |
Switches from “priming uv cache” to building a persistent venv at image build time. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
This PR aims to make container-based builds more reliable and reproducible by ensuring build outputs are available locally, dependencies are locked, and certain stages can be skipped when outputs already exist.
Changes:
- Add
uv.lockto pin Python dependency resolution for reproducible installs. - Update Docker build flow to create/use a prebuilt virtualenv in the builder image and to
--loadbuildx outputs into the local Docker daemon. - Add initramfs stage idempotency to skip rebuilds when an initramfs artifact already exists (unless forced).
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
uv.lock |
Introduces a uv lockfile to make dependency resolution reproducible. |
captain/docker.py |
Adds --load to docker buildx build so built images are available in the local daemon. |
captain/cli/_stages.py |
Skips initramfs rebuild when an existing *.cpio* is found unless forced. |
Dockerfile |
Builds a persistent venv and runs uv sync --frozen during image build to avoid recreating envs at runtime. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- from tinkerbell#64 Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
- Use glob("*.cpio*") for initramfs skip check, consistent with
artifacts.py and iso.py, so it works regardless of compression format.
- Copy uv.lock into Docker image and use "uv sync --frozen" to enforce
lockfile-pinned dependencies instead of resolving fresh each build.
Signed-off-by: Jacob Weinstock <jakobweinstock@gmail.com>
32b9e60 to
6de77ed
Compare
| # Install project dependencies into a persistent venv so that | ||
| # `uv run` inside the container reuses it instead of recreating one. | ||
| COPY pyproject.toml /opt/captain/pyproject.toml | ||
| COPY uv.lock /opt/captain/uv.lock |
|
|
||
| # --- idempotency -------------------------------------------------- | ||
| initramfs_image = cfg.initramfs_output / "image.cpio.zst" | ||
| existing = sorted(cfg.initramfs_output.glob("*.cpio*")) |
Description
Fixes: #
How Has This Been Tested?
How are existing users impacted? What migration steps/scripts do we need?
Checklist:
I have: