Stop the EL9 stage from depending on its own curl binary

369e3b3 · Gabriel Morell · 2026-09-19 03:07

2 files +29 -29
Message
{commit_body(@commit)}

Files changed

modified cli/Dockerfile
+29 −29
@@ -98,48 +98,48 @@ RUN set -eux; \
98 98
99 99 # ── .rpm, on EL9 ─────────────────────────────────────────────────────
100 100
101 −# A CA bundle this stage can actually read.
101 +# The EL9 stage does not download its own toolchain, because the `curl`
102 +# binary in that image cannot load a CA file on the forge's runner:
102 103 #
103 −# EL9 ships one, and on a developer's machine it works — but on the
104 −# forge's own runner every HTTPS fetch out of this image dies with
105 −# `curl: (77) error setting certificate file`, with ca-certificates
106 −# installed at the same version and `update-ca-trust extract` run first.
107 −# The Debian stage downloads happily on that same host, so it is this
108 −# image's trust store specifically, not the network: EL9 assembles that
109 −# bundle out of hardlinks, and a snapshotter that mishandles them (an
110 −# overlayfs with metacopy on, say) leaves a file present and unreadable
111 −# exactly like this.
104 +# curl: (77) error setting certificate file: <any path>
112 105 #
113 −# Rather than keep guessing at the host, the stage carries its own
114 −# bundle, taken from the image the .deb is built with — already pulled,
115 −# and it demonstrably reaches the network. (debian:trixie-slim would be
116 −# the tidier source and ships no ca-certificates at all.)
117 −# CURL_CA_BUNDLE covers curl and cargo's libcurl; SSL_CERT_FILE covers
118 −# rustup and anything OpenSSL- or rustls-based.
119 −FROM docker.io/rust:${RUST_VERSION}-trixie AS certs
106 +# Not the file and not the network. In the same RUN, one command
107 +# earlier, dnf pulls 50 MB of metadata and 279 packages over HTTPS
108 +# through libcurl using this very bundle; the same image does it
109 +# happily on a developer's machine. So the toolchain is copied in whole
110 +# from the Debian stage instead — the official x86_64-unknown-linux-gnu
111 +# builds target glibc 2.17, so rustc and cargo run here unmodified, and
112 +# cargo's own libcurl is not the binary that's broken.
113 +FROM docker.io/rust:${RUST_VERSION}-trixie AS toolchain
120 114
121 115 FROM docker.io/rockylinux/rockylinux:9 AS rpm-builder
122 116
123 −COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/pki/ca-trust/gg-ca-bundle.pem
124 −ENV CURL_CA_BUNDLE=/etc/pki/ca-trust/gg-ca-bundle.pem \
125 − SSL_CERT_FILE=/etc/pki/ca-trust/gg-ca-bundle.pem
126 −
127 −# EL9's own rust is far older than this crate's edition, so the
128 −# toolchain comes from rustup — the same split the server image makes
129 −# for the NIF crates on trixie.
130 −ARG RUST_VERSION
131 117 ENV RUSTUP_HOME=/usr/local/rustup \
132 118 CARGO_HOME=/usr/local/cargo \
133 119 PATH=/usr/local/cargo/bin:${PATH}
120 +COPY --from=toolchain /usr/local/rustup /usr/local/rustup
121 +COPY --from=toolchain /usr/local/cargo /usr/local/cargo
122 +
123 +# A CA bundle from an image that demonstrably reaches the network on
124 +# that host, for everything here that still fetches: dnf, and cargo
125 +# pulling crates.
126 +COPY --from=toolchain /etc/ssl/certs/ca-certificates.crt /etc/pki/ca-trust/gg-ca-bundle.pem
127 +ENV CURL_CA_BUNDLE=/etc/pki/ca-trust/gg-ca-bundle.pem \
128 + SSL_CERT_FILE=/etc/pki/ca-trust/gg-ca-bundle.pem \
129 + CARGO_HTTP_CAINFO=/etc/pki/ca-trust/gg-ca-bundle.pem
130 +
131 +# The curl line is a probe, not a dependency: it records in the build
132 +# log whether this host still has the fault, and nothing below needs it
133 +# to pass. (Comments can't live inside the RUN — a Dockerfile joins
134 +# continued lines into one, and a `#` would swallow the rest.)
134 135 RUN set -eux; \
135 136 dnf -y install gcc gcc-c++ make cmake perl; \
136 137 dnf clean all; \
137 − curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs -o /tmp/rustup-init.sh; \
138 − sh /tmp/rustup-init.sh -y --no-modify-path --profile minimal \
139 − --default-toolchain "${RUST_VERSION}"; \
140 − rm /tmp/rustup-init.sh; \
141 138 rustc --version; \
142 139 cargo --version; \
140 + { curl -sSf -o /dev/null https://static.rust-lang.org/ \
141 + && echo "probe: the curl binary works here" \
142 + || echo "probe: the curl binary cannot load a CA file here"; }; \
143 143 cargo install --locked cargo-generate-rpm
144 144
145 145 WORKDIR /src/cli

Parents: c90ac30