fix(sandbox): install supported node in common image

This commit is contained in:
Vincent Koc 2026-06-24 22:34:54 +08:00
parent b58e6e0734
commit eabc12b7d6
No known key found for this signature in database
6 changed files with 30 additions and 8 deletions

View file

@ -57,11 +57,10 @@ jobs:
BASE_IMAGE="openclaw-sandbox-smoke-base:bookworm-slim" \
TARGET_IMAGE="openclaw-sandbox-common-smoke:bookworm-slim" \
PACKAGES="ca-certificates" \
INSTALL_PNPM=0 \
INSTALL_BUN=0 \
INSTALL_BREW=0 \
FINAL_USER=sandbox \
scripts/sandbox-common-setup.sh
u="$(timeout --kill-after=30s 2m docker run --rm openclaw-sandbox-common-smoke:bookworm-slim sh -lc 'id -un')"
test "$u" = "sandbox"
timeout --kill-after=30s 2m docker run --rm openclaw-sandbox-common-smoke:bookworm-slim sh -lc \
'set -e; test "$(id -un)" = sandbox; node --version; pnpm --version'

View file

@ -415,7 +415,7 @@ If you installed OpenClaw via `npm install -g openclaw`, use the inline `docker
</Step>
<Step title="Optional: build the common image">
For a more functional sandbox image with common tooling (for example `curl`, `jq`, `nodejs`, `python3`, `git`):
For a more functional sandbox image with common tooling (for example `curl`, `jq`, Node 24, pnpm, `python3`, and `git`):
From a source checkout:

View file

@ -7,7 +7,9 @@ USER root
ENV DEBIAN_FRONTEND=noninteractive
ARG PACKAGES="curl wget jq coreutils grep nodejs npm python3 git ca-certificates golang-go rustc cargo unzip pkg-config libasound2-dev build-essential file"
ARG PACKAGES="curl wget jq coreutils grep python3 git ca-certificates golang-go rustc cargo unzip pkg-config libasound2-dev build-essential file"
ARG INSTALL_NODE=1
ARG NODE_MAJOR=24
ARG INSTALL_PNPM=1
ARG INSTALL_BUN=1
ARG BUN_INSTALL_DIR=/opt/bun
@ -26,7 +28,18 @@ RUN --mount=type=cache,id=openclaw-sandbox-common-apt-cache,target=/var/cache/ap
apt-get update \
&& apt-get install -y --no-install-recommends ${PACKAGES}
RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi
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 \
if [ "${INSTALL_NODE}" = "1" ]; then \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates curl; \
curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -; \
apt-get install -y --no-install-recommends nodejs; \
node --version; \
npm --version; \
fi
RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm && pnpm --version; fi
RUN if [ "${INSTALL_BUN}" = "1" ]; then \
curl -fsSL https://bun.sh/install | bash; \

View file

@ -6,7 +6,9 @@ source "$ROOT_DIR/scripts/lib/docker-build.sh"
BASE_IMAGE="${BASE_IMAGE:-openclaw-sandbox:bookworm-slim}"
TARGET_IMAGE="${TARGET_IMAGE:-openclaw-sandbox-common:bookworm-slim}"
PACKAGES="${PACKAGES:-curl wget jq coreutils grep nodejs npm python3 git ca-certificates golang-go rustc cargo unzip pkg-config libasound2-dev build-essential file}"
PACKAGES="${PACKAGES:-curl wget jq coreutils grep python3 git ca-certificates golang-go rustc cargo unzip pkg-config libasound2-dev build-essential file}"
INSTALL_NODE="${INSTALL_NODE:-1}"
NODE_MAJOR="${NODE_MAJOR:-24}"
INSTALL_PNPM="${INSTALL_PNPM:-1}"
INSTALL_BUN="${INSTALL_BUN:-1}"
BUN_INSTALL_DIR="${BUN_INSTALL_DIR:-/opt/bun}"
@ -30,6 +32,8 @@ docker_build_exec \
-f "$ROOT_DIR/scripts/docker/sandbox/Dockerfile.common" \
--build-arg BASE_IMAGE="${BASE_IMAGE}" \
--build-arg PACKAGES="${PACKAGES}" \
--build-arg INSTALL_NODE="${INSTALL_NODE}" \
--build-arg NODE_MAJOR="${NODE_MAJOR}" \
--build-arg INSTALL_PNPM="${INSTALL_PNPM}" \
--build-arg INSTALL_BUN="${INSTALL_BUN}" \
--build-arg BUN_INSTALL_DIR="${BUN_INSTALL_DIR}" \

View file

@ -92,8 +92,11 @@ describe("docker build cache layout", () => {
it("does not leave empty shell continuation lines in sandbox-common", async () => {
const dockerfile = await readRepoFile("scripts/docker/sandbox/Dockerfile.common");
expect(dockerfile).not.toContain("apt-get install -y --no-install-recommends ${PACKAGES} \\");
expect(dockerfile).toContain("ARG INSTALL_NODE=1");
expect(dockerfile).toContain("ARG NODE_MAJOR=24");
expect(dockerfile).toContain('curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x"');
expect(dockerfile).toContain(
'RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi',
'RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm && pnpm --version; fi',
);
});

View file

@ -14,6 +14,9 @@ describe("sandbox common smoke workflow", () => {
expect(workflow).toContain(
"timeout --kill-after=30s 2m docker run --rm openclaw-sandbox-common-smoke:bookworm-slim",
);
expect(workflow).toContain("node --version");
expect(workflow).toContain("pnpm --version");
expect(workflow).not.toContain("INSTALL_PNPM=0");
expect(workflow).not.toMatch(/(^|\n)\s+docker build -t openclaw-sandbox-smoke-base/u);
expect(workflow).not.toContain(
'u="$(docker run --rm openclaw-sandbox-common-smoke:bookworm-slim',