From 6fc3839cb56d4eb08cb43764fcbe7bd72e9bc50a Mon Sep 17 00:00:00 2001 From: Jacob Tomlinson Date: Fri, 13 Mar 2026 19:11:18 +0000 Subject: [PATCH] docker: add DEBIAN_FRONTEND and --no-install-recommends to apt-get upgrade Prevents debconf hangs during Docker builds and avoids pulling in recommended packages that silently grow the image. Co-Authored-By: Claude --- Dockerfile | 164 +++++++++---------- Dockerfile.sandbox | 16 +- Dockerfile.sandbox-browser | 30 ++-- Dockerfile.sandbox-common | 6 +- scripts/docker/cleanup-smoke/Dockerfile | 8 +- scripts/docker/install-sh-e2e/Dockerfile | 10 +- scripts/docker/install-sh-nonroot/Dockerfile | 24 +-- scripts/docker/install-sh-smoke/Dockerfile | 26 +-- 8 files changed, 142 insertions(+), 142 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6b0f90fac4d..6484df722b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,12 +29,12 @@ ARG OPENCLAW_EXTENSIONS COPY extensions /tmp/extensions # Copy package.json for opted-in extensions so pnpm resolves their deps. RUN mkdir -p /out && \ - for ext in $OPENCLAW_EXTENSIONS; do \ - if [ -f "/tmp/extensions/$ext/package.json" ]; then \ - mkdir -p "/out/$ext" && \ - cp "/tmp/extensions/$ext/package.json" "/out/$ext/package.json"; \ - fi; \ - done + for ext in $OPENCLAW_EXTENSIONS; do \ + if [ -f "/tmp/extensions/$ext/package.json" ]; then \ + mkdir -p "/out/$ext" && \ + cp "/tmp/extensions/$ext/package.json" "/out/$ext/package.json"; \ + fi; \ + done # ── Stage 2: Build ────────────────────────────────────────────── FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS build @@ -42,15 +42,15 @@ FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS build # Install Bun (required for build scripts). Retry the whole bootstrap flow to # tolerate transient 5xx failures from bun.sh/GitHub during CI image builds. RUN set -eux; \ - for attempt in 1 2 3 4 5; do \ - if curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL https://bun.sh/install | bash; then \ - break; \ - fi; \ - if [ "$attempt" -eq 5 ]; then \ - exit 1; \ - fi; \ - sleep $((attempt * 2)); \ - done + for attempt in 1 2 3 4 5; do \ + if curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL https://bun.sh/install | bash; then \ + break; \ + fi; \ + if [ "$attempt" -eq 5 ]; then \ + exit 1; \ + fi; \ + sleep $((attempt * 2)); \ + done ENV PATH="/root/.bun/bin:${PATH}" RUN corepack enable @@ -66,28 +66,28 @@ COPY --from=ext-deps /out/ ./extensions/ # Reduce OOM risk on low-memory hosts during dependency installation. # Docker builds on small VMs may otherwise fail with "Killed" (exit 137). RUN --mount=type=cache,id=openclaw-pnpm-store,target=/root/.local/share/pnpm/store,sharing=locked \ - NODE_OPTIONS=--max-old-space-size=2048 pnpm install --frozen-lockfile + NODE_OPTIONS=--max-old-space-size=2048 pnpm install --frozen-lockfile COPY . . # Normalize extension paths now so runtime COPY preserves safe modes # without adding a second full extensions layer. RUN for dir in /app/extensions /app/.agent /app/.agents; do \ - if [ -d "$dir" ]; then \ - find "$dir" -type d -exec chmod 755 {} +; \ - find "$dir" -type f -exec chmod 644 {} +; \ - fi; \ - done + if [ -d "$dir" ]; then \ + find "$dir" -type d -exec chmod 755 {} +; \ + find "$dir" -type f -exec chmod 644 {} +; \ + fi; \ + done # A2UI bundle may fail under QEMU cross-compilation (e.g. building amd64 # on Apple Silicon). CI builds natively per-arch so this is a no-op there. # Stub it so local cross-arch builds still succeed. RUN pnpm canvas:a2ui:bundle || \ - (echo "A2UI bundle: creating stub (non-fatal)" && \ - mkdir -p src/canvas-host/a2ui && \ - echo "/* A2UI bundle unavailable in this build */" > src/canvas-host/a2ui/a2ui.bundle.js && \ - echo "stub" > src/canvas-host/a2ui/.bundle.hash && \ - rm -rf vendor/a2ui apps/shared/OpenClawKit/Tools/CanvasA2UI) + (echo "A2UI bundle: creating stub (non-fatal)" && \ + mkdir -p src/canvas-host/a2ui && \ + echo "/* A2UI bundle unavailable in this build */" > src/canvas-host/a2ui/a2ui.bundle.js && \ + echo "stub" > src/canvas-host/a2ui/.bundle.hash && \ + rm -rf vendor/a2ui apps/shared/OpenClawKit/Tools/CanvasA2UI) RUN pnpm build:docker # Force pnpm for UI build (Bun may fail on ARM/Synology architectures) ENV OPENCLAW_PREFER_PNPM=1 @@ -97,7 +97,7 @@ RUN pnpm ui:build # runtime assets into the final image. FROM build AS runtime-assets RUN CI=true pnpm prune --prod && \ - find dist -type f \( -name '*.d.ts' -o -name '*.d.mts' -o -name '*.d.cts' -o -name '*.map' \) -delete + find dist -type f \( -name '*.d.ts' -o -name '*.d.mts' -o -name '*.d.cts' -o -name '*.map' \) -delete # ── Runtime base images ───────────────────────────────────────── FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS base-default @@ -130,11 +130,11 @@ WORKDIR /app # Install system utilities present in bookworm but missing in bookworm-slim. # On the full bookworm image these are already installed (apt-get is a no-op). RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ - apt-get update && \ - apt-get upgrade -y && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - procps hostname curl git openssl + --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + procps hostname curl git openssl RUN chown node:node /app @@ -151,27 +151,27 @@ COPY --from=runtime-assets --chown=node:node /app/docs ./docs # first-run network fetch when invoking pnpm. ENV COREPACK_HOME=/usr/local/share/corepack RUN install -d -m 0755 "$COREPACK_HOME" && \ - corepack enable && \ - for attempt in 1 2 3 4 5; do \ - if corepack prepare "$(node -p "require('./package.json').packageManager")" --activate; then \ - break; \ - fi; \ - if [ "$attempt" -eq 5 ]; then \ - exit 1; \ - fi; \ - sleep $((attempt * 2)); \ - done && \ - chmod -R a+rX "$COREPACK_HOME" + corepack enable && \ + for attempt in 1 2 3 4 5; do \ + if corepack prepare "$(node -p "require('./package.json').packageManager")" --activate; then \ + break; \ + fi; \ + if [ "$attempt" -eq 5 ]; then \ + exit 1; \ + fi; \ + sleep $((attempt * 2)); \ + done && \ + chmod -R a+rX "$COREPACK_HOME" # Install additional system packages needed by your skills or extensions. # Example: docker build --build-arg OPENCLAW_DOCKER_APT_PACKAGES="python3 wget" . ARG OPENCLAW_DOCKER_APT_PACKAGES="" RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ - if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $OPENCLAW_DOCKER_APT_PACKAGES; \ - fi + --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ + if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $OPENCLAW_DOCKER_APT_PACKAGES; \ + fi # Optionally install Chromium and Xvfb for browser automation. # Build with: docker build --build-arg OPENCLAW_INSTALL_BROWSER=1 ... @@ -179,15 +179,15 @@ RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,shar # Must run after node_modules COPY so playwright-core is available. ARG OPENCLAW_INSTALL_BROWSER="" RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ - if [ -n "$OPENCLAW_INSTALL_BROWSER" ]; then \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends xvfb && \ - mkdir -p /home/node/.cache/ms-playwright && \ - PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright \ - node /app/node_modules/playwright-core/cli.js install --with-deps chromium && \ - chown -R node:node /home/node/.cache/ms-playwright; \ - fi + --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ + if [ -n "$OPENCLAW_INSTALL_BROWSER" ]; then \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends xvfb && \ + mkdir -p /home/node/.cache/ms-playwright && \ + PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright \ + node /app/node_modules/playwright-core/cli.js install --with-deps chromium && \ + chown -R node:node /home/node/.cache/ms-playwright; \ + fi # Optionally install Docker CLI for sandbox container management. # Build with: docker build --build-arg OPENCLAW_INSTALL_DOCKER_CLI=1 ... @@ -196,34 +196,34 @@ RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,shar ARG OPENCLAW_INSTALL_DOCKER_CLI="" ARG OPENCLAW_DOCKER_GPG_FINGERPRINT="9DC858229FC7DD38854AE2D88D81803C0EBFCD88" RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ - if [ -n "$OPENCLAW_INSTALL_DOCKER_CLI" ]; then \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - ca-certificates curl gnupg && \ - install -m 0755 -d /etc/apt/keyrings && \ - # Verify Docker apt signing key fingerprint before trusting it as a root key. - # Update OPENCLAW_DOCKER_GPG_FINGERPRINT when Docker rotates release keys. - curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg.asc && \ - expected_fingerprint="$(printf '%s' "$OPENCLAW_DOCKER_GPG_FINGERPRINT" | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]')" && \ - actual_fingerprint="$(gpg --batch --show-keys --with-colons /tmp/docker.gpg.asc | awk -F: '$1 == "fpr" { print toupper($10); exit }')" && \ - if [ -z "$actual_fingerprint" ] || [ "$actual_fingerprint" != "$expected_fingerprint" ]; then \ - echo "ERROR: Docker apt key fingerprint mismatch (expected $expected_fingerprint, got ${actual_fingerprint:-})" >&2; \ - exit 1; \ - fi && \ - gpg --dearmor -o /etc/apt/keyrings/docker.gpg /tmp/docker.gpg.asc && \ - rm -f /tmp/docker.gpg.asc && \ - chmod a+r /etc/apt/keyrings/docker.gpg && \ - printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable\n' \ - "$(dpkg --print-architecture)" > /etc/apt/sources.list.d/docker.list && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - docker-ce-cli docker-compose-plugin; \ - fi + --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ + if [ -n "$OPENCLAW_INSTALL_DOCKER_CLI" ]; then \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg && \ + install -m 0755 -d /etc/apt/keyrings && \ + # Verify Docker apt signing key fingerprint before trusting it as a root key. + # Update OPENCLAW_DOCKER_GPG_FINGERPRINT when Docker rotates release keys. + curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg.asc && \ + expected_fingerprint="$(printf '%s' "$OPENCLAW_DOCKER_GPG_FINGERPRINT" | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]')" && \ + actual_fingerprint="$(gpg --batch --show-keys --with-colons /tmp/docker.gpg.asc | awk -F: '$1 == "fpr" { print toupper($10); exit }')" && \ + if [ -z "$actual_fingerprint" ] || [ "$actual_fingerprint" != "$expected_fingerprint" ]; then \ + echo "ERROR: Docker apt key fingerprint mismatch (expected $expected_fingerprint, got ${actual_fingerprint:-})" >&2; \ + exit 1; \ + fi && \ + gpg --dearmor -o /etc/apt/keyrings/docker.gpg /tmp/docker.gpg.asc && \ + rm -f /tmp/docker.gpg.asc && \ + chmod a+r /etc/apt/keyrings/docker.gpg && \ + printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable\n' \ + "$(dpkg --print-architecture)" > /etc/apt/sources.list.d/docker.list && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + docker-ce-cli docker-compose-plugin; \ + fi # Expose the CLI binary without requiring npm global writes as non-root. RUN ln -sf /app/openclaw.mjs /usr/local/bin/openclaw \ - && chmod 755 /app/openclaw.mjs + && chmod 755 /app/openclaw.mjs ENV NODE_ENV=production diff --git a/Dockerfile.sandbox b/Dockerfile.sandbox index c8576dce347..8b91b15dddf 100644 --- a/Dockerfile.sandbox +++ b/Dockerfile.sandbox @@ -7,15 +7,15 @@ ENV DEBIAN_FRONTEND=noninteractive RUN --mount=type=cache,id=openclaw-sandbox-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=openclaw-sandbox-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update \ - && apt-get upgrade -y \ + && apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - curl \ - git \ - jq \ - python3 \ - ripgrep + bash \ + ca-certificates \ + curl \ + git \ + jq \ + python3 \ + ripgrep RUN useradd --create-home --shell /bin/bash sandbox USER sandbox diff --git a/Dockerfile.sandbox-browser b/Dockerfile.sandbox-browser index 2085031ec7c..e4362d7e199 100644 --- a/Dockerfile.sandbox-browser +++ b/Dockerfile.sandbox-browser @@ -7,22 +7,22 @@ ENV DEBIAN_FRONTEND=noninteractive RUN --mount=type=cache,id=openclaw-sandbox-bookworm-apt-cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=openclaw-sandbox-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update \ - && apt-get upgrade -y \ + && apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - chromium \ - curl \ - fonts-liberation \ - fonts-noto-color-emoji \ - git \ - jq \ - novnc \ - python3 \ - socat \ - websockify \ - x11vnc \ - xvfb + bash \ + ca-certificates \ + chromium \ + curl \ + fonts-liberation \ + fonts-noto-color-emoji \ + git \ + jq \ + novnc \ + python3 \ + socat \ + websockify \ + x11vnc \ + xvfb COPY --chmod=755 scripts/sandbox-browser-entrypoint.sh /usr/local/bin/openclaw-sandbox-browser diff --git a/Dockerfile.sandbox-common b/Dockerfile.sandbox-common index 35cd605157c..879905c4dc7 100644 --- a/Dockerfile.sandbox-common +++ b/Dockerfile.sandbox-common @@ -24,7 +24,7 @@ ENV PATH=${BUN_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/sbin RUN --mount=type=cache,id=openclaw-sandbox-common-apt-cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=openclaw-sandbox-common-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update \ - && apt-get upgrade -y \ + && apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends ${PACKAGES} RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi @@ -32,7 +32,7 @@ RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi RUN if [ "${INSTALL_BUN}" = "1" ]; then \ curl -fsSL https://bun.sh/install | bash; \ ln -sf "${BUN_INSTALL_DIR}/bin/bun" /usr/local/bin/bun; \ -fi + fi RUN if [ "${INSTALL_BREW}" = "1" ]; then \ if ! id -u linuxbrew >/dev/null 2>&1; then useradd -m -s /bin/bash linuxbrew; fi; \ @@ -42,7 +42,7 @@ RUN if [ "${INSTALL_BREW}" = "1" ]; then \ if [ ! -e "${BREW_INSTALL_DIR}/Library" ]; then ln -s "${BREW_INSTALL_DIR}/Homebrew/Library" "${BREW_INSTALL_DIR}/Library"; fi; \ if [ ! -x "${BREW_INSTALL_DIR}/bin/brew" ]; then echo \"brew install failed\"; exit 1; fi; \ ln -sf "${BREW_INSTALL_DIR}/bin/brew" /usr/local/bin/brew; \ -fi + fi # Default is sandbox, but allow BASE_IMAGE overrides to select another final user. USER ${FINAL_USER} diff --git a/scripts/docker/cleanup-smoke/Dockerfile b/scripts/docker/cleanup-smoke/Dockerfile index a5736cd8e9e..ca1b64f60fa 100644 --- a/scripts/docker/cleanup-smoke/Dockerfile +++ b/scripts/docker/cleanup-smoke/Dockerfile @@ -5,11 +5,11 @@ FROM node:24-bookworm-slim@sha256:b4687aef2571c632a1953695ce4d61d6462a7eda471fe6 RUN --mount=type=cache,id=openclaw-cleanup-smoke-apt-cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=openclaw-cleanup-smoke-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update \ - && apt-get upgrade -y \ + && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - git + bash \ + ca-certificates \ + git WORKDIR /repo COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ diff --git a/scripts/docker/install-sh-e2e/Dockerfile b/scripts/docker/install-sh-e2e/Dockerfile index fefedd56f07..bce7ff4180a 100644 --- a/scripts/docker/install-sh-e2e/Dockerfile +++ b/scripts/docker/install-sh-e2e/Dockerfile @@ -5,12 +5,12 @@ FROM node:24-bookworm-slim@sha256:b4687aef2571c632a1953695ce4d61d6462a7eda471fe6 RUN --mount=type=cache,id=openclaw-install-sh-e2e-apt-cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=openclaw-install-sh-e2e-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update \ - && apt-get upgrade -y \ + && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - curl \ - git + bash \ + ca-certificates \ + curl \ + git COPY install-sh-common/version-parse.sh /usr/local/install-sh-common/version-parse.sh COPY --chmod=755 run.sh /usr/local/bin/openclaw-install-e2e diff --git a/scripts/docker/install-sh-nonroot/Dockerfile b/scripts/docker/install-sh-nonroot/Dockerfile index d95678ad00e..45982b26d11 100644 --- a/scripts/docker/install-sh-nonroot/Dockerfile +++ b/scripts/docker/install-sh-nonroot/Dockerfile @@ -6,20 +6,20 @@ RUN --mount=type=cache,id=openclaw-install-sh-nonroot-apt-cache,target=/var/cach --mount=type=cache,id=openclaw-install-sh-nonroot-apt-lists,target=/var/lib/apt,sharing=locked \ set -eux; \ for attempt in 1 2 3; do \ - if apt-get update -o Acquire::Retries=3; then break; fi; \ - echo "apt-get update failed (attempt ${attempt})" >&2; \ - if [ "${attempt}" -eq 3 ]; then exit 1; fi; \ - sleep 3; \ + if apt-get update -o Acquire::Retries=3; then break; fi; \ + echo "apt-get update failed (attempt ${attempt})" >&2; \ + if [ "${attempt}" -eq 3 ]; then exit 1; fi; \ + sleep 3; \ done; \ - apt-get -o Acquire::Retries=3 upgrade -y; \ + DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 upgrade -y --no-install-recommends; \ apt-get -o Acquire::Retries=3 install -y --no-install-recommends \ - bash \ - ca-certificates \ - curl \ - g++ \ - make \ - python3 \ - sudo + bash \ + ca-certificates \ + curl \ + g++ \ + make \ + python3 \ + sudo RUN useradd -m -s /bin/bash app \ && echo "app ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/app diff --git a/scripts/docker/install-sh-smoke/Dockerfile b/scripts/docker/install-sh-smoke/Dockerfile index 7baf20a932b..732cffe8c57 100644 --- a/scripts/docker/install-sh-smoke/Dockerfile +++ b/scripts/docker/install-sh-smoke/Dockerfile @@ -6,21 +6,21 @@ RUN --mount=type=cache,id=openclaw-install-sh-smoke-apt-cache,target=/var/cache/ --mount=type=cache,id=openclaw-install-sh-smoke-apt-lists,target=/var/lib/apt,sharing=locked \ set -eux; \ for attempt in 1 2 3; do \ - if apt-get update -o Acquire::Retries=3; then break; fi; \ - echo "apt-get update failed (attempt ${attempt})" >&2; \ - if [ "${attempt}" -eq 3 ]; then exit 1; fi; \ - sleep 3; \ + if apt-get update -o Acquire::Retries=3; then break; fi; \ + echo "apt-get update failed (attempt ${attempt})" >&2; \ + if [ "${attempt}" -eq 3 ]; then exit 1; fi; \ + sleep 3; \ done; \ - apt-get -o Acquire::Retries=3 upgrade -y; \ + DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 upgrade -y --no-install-recommends; \ apt-get -o Acquire::Retries=3 install -y --no-install-recommends \ - bash \ - ca-certificates \ - curl \ - git \ - g++ \ - make \ - python3 \ - sudo + bash \ + ca-certificates \ + curl \ + git \ + g++ \ + make \ + python3 \ + sudo COPY install-sh-common/cli-verify.sh /usr/local/install-sh-common/cli-verify.sh COPY install-sh-common/version-parse.sh /usr/local/install-sh-common/version-parse.sh