From c26d5fac7800d854845e3ff576413736989af63c Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 17 Apr 2026 14:39:13 +0800 Subject: [PATCH] fix(ci): harden Dockerfile.ci against transient Ubuntu mirror failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI image build failed with: E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/... Connection failed [IP: 91.189.92.22 80] ERROR: process "/bin/sh -c apt-get update && apt-get install ..." did not complete successfully: exit code: 100 archive.ubuntu.com periodically returns "connection refused" on individual regional mirrors. Without retry logic a single failed fetch nukes the whole Docker build. Three defenses, layered: 1. /etc/apt/apt.conf.d/80-retries — apt fetches each package up to 5 times with a 30s timeout. Handles per-package flakes. 2. Shell-loop retry around the whole apt-get step (x3, 10s sleep) — handles the case where apt-get update itself can't reach any mirror. 3. --retry 5 --retry-delay 5 --retry-connrefused on all curl fetches (bun install script, GitHub CLI keyring, NodeSource setup script). Applied to every apt-get and curl call in the Dockerfile. No behavior change on happy path — only kicks in when mirrors blip. Fixes the build-image job that was blocking CI on the /plan-tune PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/docker/Dockerfile.ci | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/.github/docker/Dockerfile.ci b/.github/docker/Dockerfile.ci index 1048bb47..f8c7f1ad 100644 --- a/.github/docker/Dockerfile.ci +++ b/.github/docker/Dockerfile.ci @@ -4,27 +4,44 @@ FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive -# System deps -RUN apt-get update && apt-get install -y --no-install-recommends \ - git curl unzip ca-certificates jq bc gpg \ +# Make apt/curl resilient to transient Ubuntu mirror failures. +# archive.ubuntu.com periodically returns connection refused on individual +# regional IPs; without retry logic a single failed fetch nukes the build. +RUN printf 'Acquire::Retries "5";\nAcquire::http::Timeout "30";\nAcquire::https::Timeout "30";\n' \ + > /etc/apt/apt.conf.d/80-retries + +# System deps (apt retries are wired in above, but also retry the whole step +# in case apt-get update itself can't reach any mirror) +RUN for i in 1 2 3; do \ + apt-get update && apt-get install -y --no-install-recommends \ + git curl unzip ca-certificates jq bc gpg && break || \ + (echo "apt-get retry $i/3 after failure"; sleep 10); \ + done \ && rm -rf /var/lib/apt/lists/* # GitHub CLI -RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ +RUN curl --retry 5 --retry-delay 5 --retry-connrefused -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ - && apt-get update && apt-get install -y --no-install-recommends gh \ + && for i in 1 2 3; do \ + apt-get update && apt-get install -y --no-install-recommends gh && break || \ + (echo "gh install retry $i/3"; sleep 10); \ + done \ && rm -rf /var/lib/apt/lists/* # Node.js 22 LTS (needed for claude CLI) -RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ - && apt-get install -y --no-install-recommends nodejs \ +RUN curl --retry 5 --retry-delay 5 --retry-connrefused -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && for i in 1 2 3; do \ + apt-get install -y --no-install-recommends nodejs && break || \ + (echo "nodejs install retry $i/3"; sleep 10); \ + done \ && rm -rf /var/lib/apt/lists/* # Bun (install to /usr/local so non-root users can access it) ENV BUN_INSTALL="/usr/local" -RUN curl -fsSL https://bun.sh/install | BUN_VERSION=1.3.10 bash +RUN curl --retry 5 --retry-delay 5 --retry-connrefused -fsSL https://bun.sh/install \ + | BUN_VERSION=1.3.10 bash # Claude CLI RUN npm i -g @anthropic-ai/claude-code