1414# Slim (bookworm-slim): docker build --build-arg OPENCLAW_VARIANT=slim .
1515ARG OPENCLAW_EXTENSIONS=""
1616ARG OPENCLAW_VARIANT=default
17+ ARG OPENCLAW_BUNDLED_PLUGIN_DIR=extensions
1718ARG OPENCLAW_DOCKER_APT_UPGRADE=1
1819ARG OPENCLAW_NODE_BOOKWORM_IMAGE="node:24-bookworm@sha256:3a09aa6354567619221ef6c45a5051b671f953f0a1924d1f819ffb236e520e6b"
1920ARG OPENCLAW_NODE_BOOKWORM_DIGEST="sha256:3a09aa6354567619221ef6c45a5051b671f953f0a1924d1f819ffb236e520e6b"
@@ -27,17 +28,19 @@ ARG OPENCLAW_NODE_BOOKWORM_SLIM_DIGEST="sha256:e8e2e91b1378f83c5b2dd15f0247f3411
2728
2829FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS ext-deps
2930ARG OPENCLAW_EXTENSIONS
30- COPY extensions /tmp/extensions
31+ ARG OPENCLAW_BUNDLED_PLUGIN_DIR
32+ COPY ${OPENCLAW_BUNDLED_PLUGIN_DIR} /tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR}
3133# Copy package.json for opted-in extensions so pnpm resolves their deps.
3234RUN mkdir -p /out && \
3335 for ext in $OPENCLAW_EXTENSIONS; do \
34- if [ -f "/tmp/extensions /$ext/package.json" ]; then \
36+ if [ -f "/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR} /$ext/package.json" ]; then \
3537 mkdir -p "/out/$ext" && \
36- cp "/tmp/extensions /$ext/package.json" "/out/$ext/package.json" ; \
38+ cp "/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR} /$ext/package.json" "/out/$ext/package.json" ; \
3739 fi; \
3840 done
3941
4042FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS build
43+ ARG OPENCLAW_BUNDLED_PLUGIN_DIR
4144
4245# Install Bun (required for build scripts). Retry the whole bootstrap flow to
4346# tolerate transient 5xx failures from bun.sh/GitHub during CI image builds.
@@ -60,8 +63,9 @@ WORKDIR /app
6063COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
6164COPY ui/package.json ./ui/package.json
6265COPY patches ./patches
66+ COPY scripts/postinstall-bundled-plugins.mjs ./scripts/postinstall-bundled-plugins.mjs
6367
64- COPY --from=ext-deps /out/ ./extensions /
68+ COPY --from=ext-deps /out/ ./${OPENCLAW_BUNDLED_PLUGIN_DIR} /
6569
6670# Reduce OOM risk on low-memory hosts during dependency installation.
6771# Docker builds on small VMs may otherwise fail with "Killed" (exit 137).
@@ -72,7 +76,7 @@ COPY . .
7276
7377# Normalize extension paths now so runtime COPY preserves safe modes
7478# without adding a second full extensions layer.
75- RUN for dir in /app/extensions /app/.agent /app/.agents; do \
79+ RUN for dir in /app/${OPENCLAW_BUNDLED_PLUGIN_DIR} /app/.agent /app/.agents; do \
7680 if [ -d "$dir" ]; then \
7781 find "$dir" -type d -exec chmod 755 {} +; \
7882 find "$dir" -type f -exec chmod 644 {} +; \
@@ -112,6 +116,7 @@ LABEL org.opencontainers.image.base.name="docker.io/library/node:24-bookworm-sli
112116
113117FROM base-${OPENCLAW_VARIANT}
114118ARG OPENCLAW_VARIANT
119+ ARG OPENCLAW_BUNDLED_PLUGIN_DIR
115120ARG OPENCLAW_DOCKER_APT_UPGRADE
116121
117122# OCI base-image metadata for downstream image consumers.
@@ -146,14 +151,14 @@ COPY --from=runtime-assets --chown=node:node /app/dist ./dist
146151COPY --from=runtime-assets --chown=node:node /app/node_modules ./node_modules
147152COPY --from=runtime-assets --chown=node:node /app/package.json .
148153COPY --from=runtime-assets --chown=node:node /app/openclaw.mjs .
149- COPY --from=runtime-assets --chown=node:node /app/extensions ./extensions
154+ COPY --from=runtime-assets --chown=node:node /app/${OPENCLAW_BUNDLED_PLUGIN_DIR} ./${OPENCLAW_BUNDLED_PLUGIN_DIR}
150155COPY --from=runtime-assets --chown=node:node /app/skills ./skills
151156COPY --from=runtime-assets --chown=node:node /app/docs ./docs
152157COPY openclaw/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
153158
154159# In npm-installed Docker images, prefer the copied source extension tree for
155160# bundled discovery so package metadata that points at source entries stays valid.
156- ENV OPENCLAW_BUNDLED_PLUGINS_DIR=/app/extensions
161+ ENV OPENCLAW_BUNDLED_PLUGINS_DIR=/app/${OPENCLAW_BUNDLED_PLUGIN_DIR}
157162
158163# Keep pnpm available in the runtime image for container-local workflows.
159164# Use a shared Corepack home so the non-root `node` user does not need a
0 commit comments