fix: bound curl fetches with timeout+retry to stop docker build hangs#58
Merged
chiro-hiro merged 1 commit intoJun 7, 2026
Merged
Conversation
Consumer docker builds (and the CI trust checks) could hang indefinitely in the fetch/install phase. Every curl fetch in dev-off ran without a timeout, so a stalled-but-open TCP connection blocked forever with no output. yarn and corepack have their own network timeouts; the bare `curl ... | bash` that fetches the build script — and the trust-script fetches — did not. Add bounded --connect-timeout/--max-time plus --retry/--retry-delay to every curl so a stalled fetch fails fast and retries transient blips instead of hanging: - dockerfile.sh: generated build RUN fetch + remote template fetch - check-gpg.sh / check-ssh.sh: checksum + allowlist fetches (CURL_OPTS array) - generate-ssh-allowed-signers.sh: GitHub .keys fetch Also restore green CI (both jobs went red after the orochi-network#57 merge): - regenerate checksum.sha256 — it was stale because orochi-network#57 changed dockerfile.sh and scripts/build-prod-node.sh without refreshing it - silence a false-positive shellcheck SC2016 on the intentional single-quoted `ENV APP_VERSION=${APP_VERSION}` (Docker, not the shell, expands it)
chiro-hiro
added a commit
to chiro-hiro/dev-off
that referenced
this pull request
Jun 7, 2026
The generated Dockerfile ran `corepack enable` only in the runner stage, even
though the build (`yarn install`/`yarn build`) happens in the builder. It worked
by accident — the orochinetwork/ubuntu:node base image already ships yarn as a
corepack shim — and contradicted the documented contract (DOCKERFILE.md:
"Enables corepack in both the builder and the runner"). If the base image ever
stopped pre-shimming yarn, the Strapi (Yarn 4 berry) build would break with no
corepack in the builder.
Emit the corepack-enable RUN layer in BOTH stages:
- Dockerfile.template: add {{builder_corepack_run}}, placed as root before the
USER switch (and before COPY, so the layer caches independently of code).
- dockerfile.sh: substitute {{builder_corepack_run}} from the same generator;
refresh the now-stale comment.
Also carries the same shellcheck SC2016 silence as orochi-network#58 so this PR is green
independently of merge order (the finding was introduced by the orochi-network#57 merge).
chiro-hiro
added a commit
that referenced
this pull request
Jun 7, 2026
…ner (#59) The generated Dockerfile ran `corepack enable` only in the runner stage, even though the build (`yarn install`/`yarn build`) happens in the builder. It worked by accident — the orochinetwork/ubuntu:node base image already ships yarn as a corepack shim — and contradicted the documented contract (DOCKERFILE.md: "Enables corepack in both the builder and the runner"). If the base image ever stopped pre-shimming yarn, the Strapi (Yarn 4 berry) build would break with no corepack in the builder. Emit the corepack-enable RUN layer in BOTH stages: - Dockerfile.template: add {{builder_corepack_run}}, placed as root before the USER switch (and before COPY, so the layer caches independently of code). - dockerfile.sh: substitute {{builder_corepack_run}} from the same generator; refresh the now-stale comment. Also carries the same shellcheck SC2016 silence as #58 so this PR is green independently of merge order (the finding was introduced by the #57 merge).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Consumer docker builds hang indefinitely in the fetch/install phase. The root cause is that every
curlfetch in dev-off runs without a timeout, so a stalled-but-open TCP connection (flaky registry, self-hosted runner behind a proxy, GitHub raw blip) blocks forever with no output.yarn/corepackcarry their own network timeouts and fail eventually — but the barecurl ... | bashthat fetches the build script inside the build RUN (and the trust-script fetches) do not, so they are the one infinite-hang vector in that phase.How it was diagnosed
while readpipes are correctly isolated.--frozen-lockfileas a deprecated alias and fails in ~10 ms (no hang).Fix
Bounded timeout + retry on all
curlfetches — a stall now fails fast and retries transient blips instead of hanging:dockerfile.sh— generated build RUN fetch (curl ... | bash) + remote template fetchcheck-gpg.sh/check-ssh.sh— checksum + allowlist fetches (via aCURL_OPTSarray)generate-ssh-allowed-signers.sh— GitHub.keysfetchThe generated build RUN's outer shell stays
set -eu(it'sdashon the Ubuntu builder —set -o pipefailis unsupported there).Also: restore green CI
mainis currently red (both failures introduced by the #57 merge); this PR brings it back to green:checksum.sha256— it was stale because fix: inject APP_VERSION from build host instead of running git inside the image #57 changeddockerfile.shandscripts/build-prod-node.shwithout refreshing it.SC2016on the intentional single-quotedENV APP_VERSION=${APP_VERSION}(Docker, not the shell, expands it).Verification
shellcheck -e SC1091over all scripts — cleanbash -non all edited scripts — clean./generate-checksums.sh+sha256sum -c --strict— fresh & matchingdockerfile.shdry-run smoke for node/next/nginx/strapi (+ strapi runtime contract, injection rejection) — passdocker buildof a node consumer end-to-end with the regenerated Dockerfile — succeeds; build RUN now carries the timeout flagsOut of scope (noted, not changed)
corepack enableis emitted in the runner stage rather than the builder stage (works today only because the base image'syarnis already a corepack shim). It causes errors, not hangs — flagging for a separate PR.