Build Docker image from source via cargo install#2595
Conversation
|
Claude finished @fnando's task in 2m 18s —— View job Claude Code Review
SummaryThe motivation makes sense — linking the binary against the runtime libs it'll actually run with is the right fix for the Blocking / high-risk
Smaller issues
Nits
The core idea (build inside the image so the binary links against the image's libs) is sound, and a two-stage Dockerfile + SHA resolution + restoring native arm64 runners would address all the major concerns while keeping the original motivation intact. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 84b82db997
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| ARG STELLAR_CLI_REV | ||
| RUN cargo install --locked \ | ||
| --git https://github.com/stellar/stellar-cli.git \ | ||
| --rev "${STELLAR_CLI_REV}" \ |
There was a problem hiding this comment.
Resolve branch refs before passing them to --rev
For workflow_dispatch runs where ref is a branch name (including the default main), the workflow passes that string through as STELLAR_CLI_REV, but Cargo documents --branch <BRANCH> separately from --rev <SHA> and cargo install --git ... --rev testbranch fails with revspec 'testbranch' not found. This means the manual Docker workflow's default branch build fails in the Dockerfile before pushing; resolve the checked-out ref to a commit SHA for this build arg, or use --branch when the input is a branch.
Useful? React with 👍 / 👎.
| RUN cargo install --locked \ | ||
| --git https://github.com/stellar/stellar-cli.git \ | ||
| --rev "${STELLAR_CLI_REV}" \ | ||
| stellar-cli |
There was a problem hiding this comment.
--rev may break release builds. cargo install --rev is intended for commit SHAs, while the workflow passes github.ref_name for release events — that is the tag name (e.g. v23.1.4). Cargo docs are explicit that --branch, --tag, and --rev are separate selectors with different semantics; relying on --rev to accept a tag name is brittle and may silently break.
Consider resolving the input to a SHA in the workflow before passing it as STELLAR_CLI_REV (e.g. git rev-parse HEAD after checkout, since the workflow already checks out the right ref), or choose the appropriate flag based on whether the input is a tag/branch/SHA.
There is also no default or guard: if someone builds the image locally without --build-arg STELLAR_CLI_REV=..., this becomes cargo install --rev "" stellar-cli, which fails with a confusing error. Adding ARG STELLAR_CLI_REV=main (or a check) would make local builds work and document the intent.
| pkg-config && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| ARG TARGETARCH |
There was a problem hiding this comment.
ARG TARGETARCH is no longer used (it was only needed to pick the pre-built binary in stellar-${TARGETARCH}/stellar). It can be removed.
| @@ -100,6 +64,8 @@ jobs: | |||
| platforms: linux/amd64,linux/arm64 | |||
There was a problem hiding this comment.
Cross-arch builds now run under QEMU emulation. The previous workflow built arm64 natively on an ubuntu-24.04-arm runner. With the build matrix removed, the linux/arm64 image is now compiled from source inside QEMU on an amd64 host. Building Rust under QEMU is typically 10–30× slower than native — for a project the size of stellar-cli this can mean very long builds (potentially exceeding the default 6-hour job timeout) and significant CI cost.
Consider keeping the multi-arch matrix and using docker/build-push-action per-arch on native runners, then assembling a manifest with docker buildx imagetools create. Or use buildx with platforms: linux/amd64 on ubuntu-latest and platforms: linux/arm64 on ubuntu-24.04-arm and merge.
Also worth adding cache-from/cache-to (e.g. GHA cache) to avoid re-compiling everything on every push.
| build-args: | | ||
| STELLAR_CLI_REV=${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref_name }} |
There was a problem hiding this comment.
For workflow_dispatch, inputs.ref can be a branch, tag, or SHA. For release, github.ref_name is the tag (e.g. v1.2.3). Both are forwarded to cargo install --rev in the Dockerfile, which expects a commit SHA (see Dockerfile comment).
Since the workflow already does actions/checkout at the right ref, the simplest fix is to resolve to a SHA here:
- name: Resolve ref to SHA
id: rev
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# ...
build-args: |
STELLAR_CLI_REV=${{ steps.rev.outputs.sha }}This makes the build reproducible and avoids the tag-vs-rev ambiguity.
|
|
||
| ENV STELLAR_CONFIG_HOME=/config | ||
| ENV STELLAR_DATA_HOME=/data | ||
| ENV STELLAR_NO_UPDATE_CHECK=1 |
There was a problem hiding this comment.
Nit: setting STELLAR_NO_UPDATE_CHECK=1 is a reasonable change for a containerized binary, but it's unrelated to the stated purpose of the PR (build from source). Worth either calling out in the description or splitting into its own commit so the history is clearer.
There was a problem hiding this comment.
Pull request overview
Replaces the Docker image build pipeline that copied a pre-built stellar binary (downloaded from a separate matrix build job) with a single cargo install --git ... --rev "${STELLAR_CLI_REV}" invocation inside the Dockerfile. This ensures the binary links against the libraries actually present in the final image, fixing the runtime libdbus error.
Changes:
- Rewrite
Dockerfileto install build toolchain (build-essential,git,pkg-config,*-devlibs) and runcargo installfrom the public git repo at a specific revision; also setSTELLAR_NO_UPDATE_CHECK=1. - Remove the
buildmatrix job and artifact upload/download steps from.github/workflows/docker.yml; thedockerjob now passesSTELLAR_CLI_REVtodocker/build-push-actionas a build-arg.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| Dockerfile | Switches from COPY of pre-built binary to in-image cargo install --git --rev; adds dev libs/toolchain and STELLAR_NO_UPDATE_CHECK=1. |
| .github/workflows/docker.yml | Drops the per-arch build job and binary upload/download; passes STELLAR_CLI_REV build-arg to the multi-platform Docker build. |
| build-args: | | ||
| STELLAR_CLI_REV=${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref_name }} |
| build-args: | | ||
| STELLAR_CLI_REV=${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref_name }} |
| RUN cargo install --locked \ | ||
| --git https://github.com/stellar/stellar-cli.git \ | ||
| --rev "${STELLAR_CLI_REV}" \ | ||
| stellar-cli |
What
The Docker image is now built from source via
cargo install --git ... --rev "${STELLAR_CLI_REV}"instead of copying a pre-built binary downloaded from a previous workflow job. Thebuildjob that produced and uploaded the binary has been removed; thedockerjob passesSTELLAR_CLI_REV(resolved frominputs.refor the release tag) as a build-arg todocker/build-push-action.Why
The previously downloaded binary didn't pick up the image's runtime dependencies, so the
libdbuserror still happened at runtime. Building from source inside the image ensures the binary links against the libraries actually present in the final image.Known limitations
N/A