Skip to content

Podman build cannot read selected-plugin Dockerfile source bind mounts on amd64 #103741

Description

@sallyom

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.

Metadata

Metadata

Assignees

Labels

maintainerMaintainer-authored PR

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions