From e8258fd4a6eb2c40d29351d75b6838438ef9b96b Mon Sep 17 00:00:00 2001 From: Sally O'Malley Date: Fri, 1 May 2026 00:11:38 -0400 Subject: [PATCH] fix(docker): restore python3 in runtime image (#75417) Signed-off-by: sallyom --- CHANGELOG.md | 1 + Dockerfile | 2 +- src/dockerfile.test.ts | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec2198d0a55..a8c745db4f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Docker: restore `python3` in the gateway runtime image after the slim-runtime switch. Fixes #75041. - Agents/commitments: keep inferred follow-ups internal when heartbeat target is none, strip raw source text from stored commitments, disable tools during due-commitment heartbeat turns, bound hidden extraction queue growth, expire stale commitments, and add QA/Docker safety coverage. Thanks @vignesh07. - Telegram/agents: keep typing indicators and optional generation tools off the reply critical path, so fresh Telegram replies no longer stall while provider catalogs and media models load. (#75360) Thanks @obviyus. - Agents/commitments: run hidden follow-up extraction on the configured agent/default model instead of falling back to direct OpenAI, so OpenAI Codex OAuth-only gateways no longer spam background API-key failures. Fixes #75334. Thanks @sene1337. diff --git a/Dockerfile b/Dockerfile index 8a26032602c..d548ed174ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -167,7 +167,7 @@ RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,shar --mount=type=cache,id=openclaw-bookworm-apt-lists,target=/var/lib/apt,sharing=locked \ apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - ca-certificates procps hostname curl git lsof openssl && \ + ca-certificates procps hostname curl git lsof openssl python3 && \ update-ca-certificates RUN chown node:node /app diff --git a/src/dockerfile.test.ts b/src/dockerfile.test.ts index efeb15d1161..3e900bc7bbf 100644 --- a/src/dockerfile.test.ts +++ b/src/dockerfile.test.ts @@ -37,7 +37,7 @@ describe("Dockerfile", () => { "FROM ${OPENCLAW_NODE_BOOKWORM_SLIM_IMAGE} AS base-runtime", ); const caInstallIndex = collapsed.indexOf( - "ca-certificates procps hostname curl git lsof openssl", + "ca-certificates procps hostname curl git lsof openssl python3", ); expect(runtimeIndex).toBeGreaterThan(-1); @@ -47,6 +47,21 @@ describe("Dockerfile", () => { expect(collapsed).toContain("update-ca-certificates"); }); + it("installs python3 in the slim runtime stage for workspace scripts", async () => { + const dockerfile = collapseDockerContinuations(await readFile(dockerfilePath, "utf8")); + const runtimeIndex = dockerfile.indexOf( + "FROM ${OPENCLAW_NODE_BOOKWORM_SLIM_IMAGE} AS base-runtime", + ); + const pythonInstallIndex = dockerfile.indexOf( + "ca-certificates procps hostname curl git lsof openssl python3", + ); + + expect(runtimeIndex).toBeGreaterThan(-1); + expect(pythonInstallIndex).toBeGreaterThan(runtimeIndex); + expect(pythonInstallIndex).toBeLessThan(dockerfile.indexOf("RUN chown node:node /app")); + expect(dockerfile).toContain("ca-certificates procps hostname curl git lsof openssl python3"); + }); + it("installs optional browser dependencies after pnpm install", async () => { const dockerfile = await readFile(dockerfilePath, "utf8"); const installIndex = dockerfile.indexOf("pnpm install --frozen-lockfile");