Repository navigation
fix(agent-server): PLTF-3565 use a minimal Debian Python/Node runtime - #5077
Conversation
Build the default Python runtime from Debian slim plus official Python and Node artifacts, and upgrade Debian packages before use. Co-authored-by: openhands <openhands@all-hands.dev>
REST API breakage checks (OpenAPI) — ✅ PASSEDResult: ✅ PASSED |
Coverage Report •
|
||||||||||||||||||||
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
This PR replaces the third-party nikolaik/python-nodejs base image with a canonical Debian runtime built from debian:trixie-slim + official Python 3.13.15 and Node 24.21.0 images. It also makes binary-minimal a strict runtime image (only bash, git, tini, tmux) while moving dev tools (compilers, sudo, uv, curl/wget, jq) to the full base-image stage.
Assessment
The change is well-structured and low-risk:
-
Published images are unaffected: Both
pythonandpython-slimCI variants useTARGET: binary, which builds from the fullbase-imagestage. All dev tools (build-essential, curl, wget, sudo, uv, jq, Chromium, Docker, gh) remain available in published images. Thebinary-minimaltarget is opt-in only. -
No server code depends on removed tools: No agent-server Python code references
curl,wget, orsudo. The server uses Python HTTP libraries for network access, and the agent terminal tool runs commands in the user workspace, not the server runtime. -
build.py default fix: The old
build.pydefault wasnikolaik/python-nodejs:python3.12-nodejs22-slim(Python 3.12), while the workflow used the 3.13 variant. This PR aligns both topython-node-runtime(Python 3.13.15), fixing a stale default. The removed PyInstaller/Python 3.12 compatibility comment (#1886) is no longer relevant since the builder stage already uses Python 3.13. -
Custom BASE_IMAGE preserved:
ARG BASE_IMAGE=python-node-runtimestill allows external image overrides. When overridden, the internalpython-node-runtimestage is simply unused by BuildKit. -
Test coverage:
test_python_image_uses_canonical_minimal_runtimeverifies the runtime stage structure, minimal/full package separation, and thatnikolaikreferences are fully removed. -
Trivy improvement: 87% vulnerability reduction (1,794 to 234 findings) in
binary-minimalwith 0 criticals, as documented in the PR description.
Risk Assessment
LOW - Infrastructure/Docker refactor. No agent behavior changes, no prompt/tool/loop logic modifications. Published images retain full tooling. The binary-minimal target is opt-in and its reduced toolset is appropriate for a strict runtime image.
Verdict: Approve. Clean separation of minimal vs. full runtime, good test coverage, and meaningful security improvement.
Automated review used the wrong decision (APPROVED instead of COMMENT) and is dismissed. Findings are reposted as a comment.
|
The review was successfully posted to GitHub with state GITHUB_REVIEW_POSTED This comment was posted by an AI agent (OpenHands). |
Resolve runtime upgrades from dated Debian snapshots and add a weekly workflow that builds, scans, and proposes the next eligible snapshot. Co-authored-by: openhands <openhands@all-hands.dev>
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
This PR replaces the third-party nikolaik/python-nodejs base image with a canonical Debian trixie runtime (python-node-runtime) built by copying Python 3.13.15 and Node.js 24.21.0 from their official images into debian:trixie-slim. It splits the Dockerfile into a strict binary-minimal runtime (Bash, Git, tmux, tini, runtime libraries only) and a full base-image stage that retains compilers, sudo, uv, and development utilities. A dated Debian snapshot with a 7-day observation period governs package upgrades, and a weekly workflow automates snapshot advancement with build + Trivy scan before opening a maintenance PR.
Analysis
The approach is sound:
- The
python-node-runtimestage correctly copies/usr/localfrom the Python image and Node binaries from the Node image, then installs only the shared libraries those runtimes need. The explicit library list (libssl3t64, libffi8, libgcc-s1, libstdc++6, libsqlite3-0, etc.) covers the known Python C-extension dependencies. - The PyInstaller spec already excludes
libgcc_s.so,libtinfo.so, andlibncursesfrom bundled binaries to prevent builder/runtime version mismatches. Since the builder usespython:3.13-bookwormand the runtime is now trixie, this exclusion remains critical and is correctly preserved. - The snapshot pinning via
debian.sourceswithCheck-Valid-Until: nopersists into downstream stages, sobase-image-minimal'sapt-get updateresolves against the same dated snapshot. CustomBASE_IMAGEsupport is preserved — non-Debian images fall through to their native package managers. - The
update_debian_snapshot.pyscript correctly computes a snapshot at least 7 days old, verifies it exists via HEAD requests to snapshot.debian.org, and replaces exactly oneARG DEBIAN_SNAPSHOT=pin. - The workflow builds and Trivy-scans
binary-minimalbefore opening the PR, and usesforce-with-leaseon a dedicated maintenance branch. - Tests cover the key invariants: snapshot age validation, Dockerfile pin replacement, workflow step ordering, and package separation between minimal and full stages.
build.pydefault changed from Python 3.12 topython-node-runtime(Python 3.13), aligning with the Dockerfile default and the builder stage which already uses Python 3.13.
Risk Assessment
LOW — This is a CI/Infrastructure change (Docker image refactor). No agent behavior, prompts, tool logic, or evaluation harness code is modified. The PR description includes concrete validation: built both binary-minimal and full image targets, verified runtime functionality (health, Bash, Git, tmux, Python, Node), passed 74 Docker build/metadata tests, and smoke-tested binary-minimal against the snapshot. Trivy findings dropped 87% (1,794 to 234) with zero critical findings.
Verdict
Worth merging — Clean Docker image refactor that reduces image size and vulnerability surface while preserving all runtime capabilities. No material issues found.
Temporarily advance the package snapshot ahead of the normal observation window and keep scheduled updates monotonic so they do not revert the exception. Co-authored-by: openhands <openhands@all-hands.dev>
Automated review used the wrong decision (APPROVED instead of COMMENT) and is dismissed. Findings are reposted as a comment.
Co-authored-by: openhands <openhands@all-hands.dev> (cherry picked from commit 4c89b68)
HUMAN:
I iterated pretty extensively with the agent to get the binary-minimal image down to what's truly minimal to pass tests.
I also brought up an agent server with the binary-minimal image and it is performing work properly.
AGENT:
Why
The published Python agent-server image uses
nikolaik/python-nodejs, which includes tooling the server does not need. This change replaces it with a canonical Debian runtime and makesbinary-minimala strict runtime image to reduce size and Trivy findings.Summary
python-node-runtimefromdebian:trixie-slimwith Python 3.13.15 and Node.js 24.21.0 copied from their official images.20260913T000000Zto pick up Debian 13.7 before the normal seven-day observation period.binary-minimal.BASE_IMAGEsupport and update Python image CI and TypeScript integration builds to use the internal runtime.binary-minimal, then opens or refreshes a maintenance PR.Trivy results
Using the same Trivy 0.74.0 vulnerability database and scanner settings, the local
binary-minimalscan improved as follows:binary-minimalThe remaining 59 high findings comprise 53 Debian findings without currently available upgrades, four npm findings, and two Python-package findings. There are no critical findings.
Issue Number
Contributes to #4643
How to Test
Local validation:
binary-minimaland full image targets./health, Bash execution, Git operations, tmux, Python, and Node inbinary-minimal.binary-minimalagainst Debian 13.7 snapshot20260913T000000Z; added 17 passing snapshot policy/workflow tests.Video/Screenshots
Not applicable.
Design Doc
Not applicable; this is a contained Docker image refactor.
Type
This pull request description was generated by an AI agent (OpenHands) on behalf of the user.
🐳 Agent Server images for this PR — GHCR package, pull/run commands, and all pushed tags (click to expand)
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdkpython-node-runtimepython-node-runtimegolang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:d1df117-pythonRun
All tags pushed for this build
About Multi-Architecture Support
d1df117-python) is a multi-arch manifest supporting both amd64 and arm64d1df117-python-amd64) are also available if needed