diff --git a/Dockerfile b/Dockerfile index f1d7163d192..d6923365b4b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7 + # Opt-in extension dependencies at build time (space-separated directory names). # Example: docker build --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel matrix" . # @@ -48,13 +50,13 @@ WORKDIR /app COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ COPY ui/package.json ./ui/package.json COPY patches ./patches -COPY scripts ./scripts 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 NODE_OPTIONS=--max-old-space-size=2048 pnpm install --frozen-lockfile +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 COPY . . @@ -117,11 +119,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 apt-get update && \ +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 && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - procps hostname curl git openssl && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* + procps hostname curl git openssl RUN chown node:node /app @@ -145,11 +147,11 @@ RUN install -d -m 0755 "$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 if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \ +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 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $OPENCLAW_DOCKER_APT_PACKAGES; \ fi # Optionally install Chromium and Xvfb for browser automation. @@ -157,15 +159,15 @@ RUN if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \ # Adds ~300MB but eliminates the 60-90s Playwright install on every container start. # Must run after node_modules COPY so playwright-core is available. ARG OPENCLAW_INSTALL_BROWSER="" -RUN if [ -n "$OPENCLAW_INSTALL_BROWSER" ]; then \ +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 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \ + chown -R node:node /home/node/.cache/ms-playwright; \ fi # Optionally install Docker CLI for sandbox container management. @@ -174,7 +176,9 @@ RUN if [ -n "$OPENCLAW_INSTALL_BROWSER" ]; then \ # Required for agents.defaults.sandbox to function in Docker deployments. ARG OPENCLAW_INSTALL_DOCKER_CLI="" ARG OPENCLAW_DOCKER_GPG_FINGERPRINT="9DC858229FC7DD38854AE2D88D81803C0EBFCD88" -RUN if [ -n "$OPENCLAW_INSTALL_DOCKER_CLI" ]; then \ +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 && \ @@ -195,9 +199,7 @@ RUN if [ -n "$OPENCLAW_INSTALL_DOCKER_CLI" ]; then \ "$(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 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \ + docker-ce-cli docker-compose-plugin; \ fi # Expose the CLI binary without requiring npm global writes as non-root. diff --git a/Dockerfile.sandbox b/Dockerfile.sandbox index a463d4a1020..fe2cc7e380b 100644 --- a/Dockerfile.sandbox +++ b/Dockerfile.sandbox @@ -1,8 +1,12 @@ +# syntax=docker/dockerfile:1.7 + FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update \ +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 install -y --no-install-recommends \ bash \ ca-certificates \ @@ -11,7 +15,6 @@ RUN apt-get update \ jq \ python3 \ ripgrep \ - && rm -rf /var/lib/apt/lists/* RUN useradd --create-home --shell /bin/bash sandbox USER sandbox diff --git a/Dockerfile.sandbox-browser b/Dockerfile.sandbox-browser index 78b0de98904..f04e4a82a62 100644 --- a/Dockerfile.sandbox-browser +++ b/Dockerfile.sandbox-browser @@ -1,8 +1,12 @@ +# syntax=docker/dockerfile:1.7 + FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update \ +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 install -y --no-install-recommends \ bash \ ca-certificates \ @@ -17,8 +21,7 @@ RUN apt-get update \ socat \ websockify \ x11vnc \ - xvfb \ - && rm -rf /var/lib/apt/lists/* + 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 71f80070adf..930aec0aef5 100644 --- a/Dockerfile.sandbox-common +++ b/Dockerfile.sandbox-common @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7 + ARG BASE_IMAGE=openclaw-sandbox:bookworm-slim FROM ${BASE_IMAGE} @@ -19,9 +21,10 @@ ENV HOMEBREW_CELLAR=${BREW_INSTALL_DIR}/Cellar ENV HOMEBREW_REPOSITORY=${BREW_INSTALL_DIR}/Homebrew ENV PATH=${BUN_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/sbin:${PATH} -RUN apt-get update \ +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 install -y --no-install-recommends ${PACKAGES} \ - && rm -rf /var/lib/apt/lists/* RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi @@ -42,4 +45,3 @@ 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 34ce3327ac7..4519ff9a385 100644 --- a/scripts/docker/cleanup-smoke/Dockerfile +++ b/scripts/docker/cleanup-smoke/Dockerfile @@ -1,15 +1,19 @@ +# syntax=docker/dockerfile:1.7 + FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45 -RUN apt-get update \ +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 install -y --no-install-recommends \ bash \ ca-certificates \ git \ - && rm -rf /var/lib/apt/lists/* WORKDIR /repo COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ -RUN corepack enable \ +RUN --mount=type=cache,id=openclaw-pnpm-store,target=/root/.local/share/pnpm/store,sharing=locked \ + corepack enable \ && pnpm install --frozen-lockfile COPY . . diff --git a/scripts/docker/install-sh-e2e/Dockerfile b/scripts/docker/install-sh-e2e/Dockerfile index 839d637a04b..05b77f45197 100644 --- a/scripts/docker/install-sh-e2e/Dockerfile +++ b/scripts/docker/install-sh-e2e/Dockerfile @@ -1,12 +1,15 @@ +# syntax=docker/dockerfile:1.7 + FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45 -RUN apt-get update \ +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 install -y --no-install-recommends \ bash \ ca-certificates \ curl \ - git \ - && rm -rf /var/lib/apt/lists/* + 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 9b7912323a4..d0c085d9f69 100644 --- a/scripts/docker/install-sh-nonroot/Dockerfile +++ b/scripts/docker/install-sh-nonroot/Dockerfile @@ -1,6 +1,10 @@ +# syntax=docker/dockerfile:1.7 + FROM ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b -RUN set -eux; \ +RUN --mount=type=cache,id=openclaw-install-sh-nonroot-apt-cache,target=/var/cache/apt,sharing=locked \ + --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; \ @@ -14,8 +18,7 @@ RUN set -eux; \ g++ \ make \ python3 \ - sudo \ - && rm -rf /var/lib/apt/lists/* + 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 eb2dcfe5226..94fdca13a31 100644 --- a/scripts/docker/install-sh-smoke/Dockerfile +++ b/scripts/docker/install-sh-smoke/Dockerfile @@ -1,6 +1,10 @@ +# syntax=docker/dockerfile:1.7 + FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45 -RUN set -eux; \ +RUN --mount=type=cache,id=openclaw-install-sh-smoke-apt-cache,target=/var/cache/apt,sharing=locked \ + --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; \ @@ -15,8 +19,7 @@ RUN set -eux; \ g++ \ make \ python3 \ - sudo \ - && rm -rf /var/lib/apt/lists/* + 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 diff --git a/scripts/e2e/Dockerfile b/scripts/e2e/Dockerfile index 9936acec8a7..257c852e654 100644 --- a/scripts/e2e/Dockerfile +++ b/scripts/e2e/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7 + FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 RUN corepack enable @@ -7,19 +9,24 @@ WORKDIR /app ENV NODE_OPTIONS="--disable-warning=ExperimentalWarning" COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json tsconfig.plugin-sdk.dts.json tsdown.config.ts vitest.config.ts vitest.e2e.config.ts openclaw.mjs ./ +COPY ui/package.json ./ui/package.json +COPY extensions/memory-core/package.json ./extensions/memory-core/package.json +COPY patches ./patches + +RUN --mount=type=cache,id=openclaw-pnpm-store,target=/root/.local/share/pnpm/store,sharing=locked \ + pnpm install --frozen-lockfile + COPY src ./src COPY test ./test COPY scripts ./scripts COPY docs ./docs COPY skills ./skills -COPY patches ./patches COPY ui ./ui COPY extensions/memory-core ./extensions/memory-core COPY vendor/a2ui/renderers/lit ./vendor/a2ui/renderers/lit COPY apps/shared/OpenClawKit/Sources/OpenClawKit/Resources ./apps/shared/OpenClawKit/Sources/OpenClawKit/Resources COPY apps/shared/OpenClawKit/Tools/CanvasA2UI ./apps/shared/OpenClawKit/Tools/CanvasA2UI -RUN pnpm install --frozen-lockfile RUN pnpm build RUN pnpm ui:build diff --git a/scripts/e2e/Dockerfile.qr-import b/scripts/e2e/Dockerfile.qr-import index f97d57891fd..a235a7f4bd2 100644 --- a/scripts/e2e/Dockerfile.qr-import +++ b/scripts/e2e/Dockerfile.qr-import @@ -1,12 +1,19 @@ +# syntax=docker/dockerfile:1.7 + FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 RUN corepack enable WORKDIR /app -COPY . . +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +COPY ui/package.json ./ui/package.json +COPY patches ./patches -RUN pnpm install --frozen-lockfile +RUN --mount=type=cache,id=openclaw-pnpm-store,target=/root/.local/share/pnpm/store,sharing=locked \ + pnpm install --frozen-lockfile + +COPY . . RUN useradd --create-home --shell /bin/bash appuser \ && chown -R appuser:appuser /app