Podman Build Cannot Reliably Read Dockerfile Source Bind-Mounted Plugin Inputs
Problem
podman build can fail while building a source image with selected plugins:
podman build \
--platform linux/amd64 \
-t quay.io/sallyom/openclaw:vault-codex-amd64 \
--build-arg OPENCLAW_EXTENSIONS=vault,codex \
--no-cache \
.
The failure happens in the Dockerfile workspace-deps stage before the main
source tree is copied into /app.
Observed Failure
Initial failure:
Error: Cannot find module '/tmp/docker-plugin-selection.mjs'
After testing a local Dockerfile change that copied the selector script instead
of bind-mounting it, the build advanced and then failed on another bind-mounted
input:
ERROR: EACCES: permission denied, open '/tmp/extensions/<plugin>/openclaw.plugin.json'
This points at Podman/Buildah access to RUN --mount=type=bind inputs from the
build context in the Dockerfile, not at the final runtime build.
Relevant Dockerfile area before the proposed fix:
RUN --mount=type=bind,source=packages,target=/tmp/packages,readonly \
--mount=type=bind,source=${OPENCLAW_BUNDLED_PLUGIN_DIR},target=/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR},readonly \
--mount=type=bind,source=scripts/lib/docker-plugin-selection.mjs,target=/tmp/docker-plugin-selection.mjs,readonly \
...
The rest of the Dockerfile also uses RUN --mount=type=cache, but those mounts
are builder-owned cache directories. They do not read files from the source
build context and are not the failing path.
Expected
A source image build with selected plugins should either:
- complete the
workspace-deps stage and continue the image build, or
- fail closed with a selected-plugin validation error if
OPENCLAW_EXTENSIONS
contains an unknown, invalid, or ambiguous plugin id.
Actual
On the failing Podman amd64 path, the source-context bind-mounted selector file
is not present at /tmp/docker-plugin-selection.mjs, so Node fails with
MODULE_NOT_FOUND. When the selector script is copied instead, Podman reaches
the next source-context bind-mounted input and can fail with EACCES.
Scope / Current Evidence
Confirmed failing:
- native amd64 Podman build over SSH
- amd64 Podman build path from an arm64 host
Observed working:
This does not look like a general RUN --mount problem. The Dockerfile's
existing cache mounts continue to work. The narrow issue is source-context bind
mounts in the early workspace-deps stage.
The arm64/macOS success does not prove the Dockerfile is portable for Podman in
general. Podman on macOS runs through a Linux VM with its own storage, security,
and mount behavior. The native amd64 host uses a different Podman/Buildah path,
and the source-context bind mount is either not materialized or not accessible
there. SELinux or other host labeling could explain the later EACCES, but the
initial MODULE_NOT_FOUND means the selector file was not available at all.
Proposed Fix
Avoid source-context RUN --mount=type=bind for the required workspace-deps
inputs. Use normal build-context COPY for the package/plugin metadata inputs
and selector script, while preserving the selected-plugin behavior added in
#103629:
COPY packages /tmp/packages
COPY ${OPENCLAW_BUNDLED_PLUGIN_DIR} /tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR}
COPY scripts/lib/docker-plugin-selection.mjs /tmp/docker-plugin-selection.mjs
RUN mkdir -p /out/packages "/out/${OPENCLAW_BUNDLED_PLUGIN_DIR}" && \
...
This preserves the same outputs consumed by later stages:
- resolve manifest ids to source dirs
- fail closed on unknown/invalid/ambiguous ids
- write
/out/openclaw-selected-plugin-dirs
- stage selected plugin
package.json files
- keep final image output unchanged for the same source tree and selection
Tradeoff: copying packages/ and ${OPENCLAW_BUNDLED_PLUGIN_DIR} into the
metadata stage can broaden cache invalidation versus source bind mounts. The
benefit is that the primary Dockerfile works across Docker BuildKit and Podman
without Podman-specific relabel mount options or a second Dockerfile path.
Verification
With the COPY change in the main Dockerfile:
podman build \
--target workspace-deps \
--platform linux/amd64 \
-t openclaw-podman-workspace-deps:probe-amd64 \
--build-arg OPENCLAW_EXTENSIONS=vault,codex \
.
The workspace-deps stage completed successfully on the amd64 Podman path that
previously failed before running the selector script.
Podman Build Cannot Reliably Read Dockerfile Source Bind-Mounted Plugin Inputs
Problem
podman buildcan fail while building a source image with selected plugins:podman build \ --platform linux/amd64 \ -t quay.io/sallyom/openclaw:vault-codex-amd64 \ --build-arg OPENCLAW_EXTENSIONS=vault,codex \ --no-cache \ .The failure happens in the Dockerfile
workspace-depsstage before the mainsource tree is copied into
/app.Observed Failure
Initial failure:
After testing a local Dockerfile change that copied the selector script instead
of bind-mounting it, the build advanced and then failed on another bind-mounted
input:
This points at Podman/Buildah access to
RUN --mount=type=bindinputs from thebuild context in the Dockerfile, not at the final runtime build.
Relevant Dockerfile area before the proposed fix:
RUN --mount=type=bind,source=packages,target=/tmp/packages,readonly \ --mount=type=bind,source=${OPENCLAW_BUNDLED_PLUGIN_DIR},target=/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR},readonly \ --mount=type=bind,source=scripts/lib/docker-plugin-selection.mjs,target=/tmp/docker-plugin-selection.mjs,readonly \ ...The rest of the Dockerfile also uses
RUN --mount=type=cache, but those mountsare builder-owned cache directories. They do not read files from the source
build context and are not the failing path.
Expected
A source image build with selected plugins should either:
workspace-depsstage and continue the image build, orOPENCLAW_EXTENSIONScontains an unknown, invalid, or ambiguous plugin id.
Actual
On the failing Podman amd64 path, the source-context bind-mounted selector file
is not present at
/tmp/docker-plugin-selection.mjs, so Node fails withMODULE_NOT_FOUND. When the selector script is copied instead, Podman reachesthe next source-context bind-mounted input and can fail with
EACCES.Scope / Current Evidence
Confirmed failing:
Observed working:
This does not look like a general
RUN --mountproblem. The Dockerfile'sexisting cache mounts continue to work. The narrow issue is source-context bind
mounts in the early
workspace-depsstage.The arm64/macOS success does not prove the Dockerfile is portable for Podman in
general. Podman on macOS runs through a Linux VM with its own storage, security,
and mount behavior. The native amd64 host uses a different Podman/Buildah path,
and the source-context bind mount is either not materialized or not accessible
there. SELinux or other host labeling could explain the later
EACCES, but theinitial
MODULE_NOT_FOUNDmeans the selector file was not available at all.Proposed Fix
Avoid source-context
RUN --mount=type=bindfor the requiredworkspace-depsinputs. Use normal build-context
COPYfor the package/plugin metadata inputsand selector script, while preserving the selected-plugin behavior added in
#103629:
This preserves the same outputs consumed by later stages:
/out/openclaw-selected-plugin-dirspackage.jsonfilesTradeoff: copying
packages/and${OPENCLAW_BUNDLED_PLUGIN_DIR}into themetadata stage can broaden cache invalidation versus source bind mounts. The
benefit is that the primary Dockerfile works across Docker BuildKit and Podman
without Podman-specific
relabelmount options or a second Dockerfile path.Verification
With the
COPYchange in the main Dockerfile:podman build \ --target workspace-deps \ --platform linux/amd64 \ -t openclaw-podman-workspace-deps:probe-amd64 \ --build-arg OPENCLAW_EXTENSIONS=vault,codex \ .The
workspace-depsstage completed successfully on the amd64 Podman path thatpreviously failed before running the selector script.