Skip to content

fix(docker): install extension dependencies in Dockerfile#37602

Open
zhddoge-ai wants to merge 2 commits intoopenclaw:mainfrom
zhddoge-ai:fix/dockerfile-extension-dependencies
Open

fix(docker): install extension dependencies in Dockerfile#37602
zhddoge-ai wants to merge 2 commits intoopenclaw:mainfrom
zhddoge-ai:fix/dockerfile-extension-dependencies

Conversation

@zhddoge-ai
Copy link
Copy Markdown

fix(docker): install extension dependencies in Dockerfile

Problem

Extension plugins like feishu failed to load in Docker with module not found errors:

Error: Cannot find module '@larksuiteoapi/node-sdk'
Require stack:
- /app/extensions/feishu/src/client.ts

The Dockerfile's initial pnpm install --frozen-lockfile ran before copying the extensions/ directory, so extension dependencies were never installed.

Solution

Added pnpm install --no-frozen-lockfile after COPY . . to ensure extension dependencies are installed before building.

Changes

  • Modified Dockerfile to add extension dependency installation step after copying source code

Testing

  • ✅ Built Docker image successfully
  • ✅ Verified /app/extensions/feishu/node_modules/@larksuiteoapi is present in container
  • ✅ Confirmed feishu plugin loads without errors
  • ✅ Gateway runs normally with all extensions functional

Impact

  • Fixes all extension plugins that require external dependencies
  • Minimal build time impact (~few seconds for extension deps)
  • No changes to runtime behavior or existing functionality

Co-Authored-By: 赵浩dong [email protected]
Co-Authored-By: Claude Sonnet 4.5 [email protected]

Install extension plugin dependencies after copying the extensions
directory to fix missing module errors for plugins like feishu.

Previously, extensions/*/package.json files were not present during
the initial `pnpm install --frozen-lockfile` step, causing extension
dependencies to be skipped. This resulted in runtime errors when
loading plugins that require external dependencies (e.g., feishu
plugin missing @larksuiteoapi/node-sdk).

The fix adds a secondary `pnpm install --no-frozen-lockfile` after
COPY . . to ensure extension dependencies are installed before
building.

Fixes #XXXX

Co-Authored-By: 赵浩东 <[email protected]>
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@openclaw-barnacle openclaw-barnacle bot added docker Docker and sandbox tooling size: XS labels Mar 6, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR fixes a real Docker build issue where extension plugins (e.g. feishu) failed to load because their dependencies were never installed — the initial pnpm install --frozen-lockfile ran before the extensions directory was copied. The fix adds a second pnpm install step after the full source copy.

Two issues with the current implementation:

  • Missing OOM guard: The original pnpm install at line 41 uses NODE_OPTIONS=--max-old-space-size=2048 specifically to prevent "Killed" (exit 137) failures on low-memory Docker hosts. The new install step at line 103 omits this, exposing the same class of failure.
  • --no-frozen-lockfile breaks reproducibility: The lockfile-enforced first install ensures every dependency is pinned. The new --no-frozen-lockfile step resolves extension packages against their semver ranges at build time, meaning two builds from the same commit can produce different node_modules. The preferred fix is to commit extension dependencies into pnpm-lock.yaml and use --frozen-lockfile here too, or restructure the COPY layers so a single frozen install covers everything.

Confidence Score: 3/5

  • Safe to merge as a functional fix, but the use of --no-frozen-lockfile introduces reproducibility and minor security concerns that should be addressed before the build pipeline is considered robust.
  • The core fix (installing extension deps after copying the extensions directory) is correct and addresses a real bug. However, the missing NODE_OPTIONS memory cap can cause OOM on low-memory hosts — the same failure mode that was already documented and guarded against for the first install step. Additionally, --no-frozen-lockfile makes extension dependency versions non-deterministic across builds, which is a meaningful reproducibility and supply-chain concern for a production Docker image.
  • Dockerfile line 103 — the new pnpm install step needs NODE_OPTIONS=--max-old-space-size=2048 and ideally should use --frozen-lockfile once the extension lockfile entries are committed.

Last reviewed commit: 7877d6d

Dockerfile Outdated
fi; \
done
# Install extension dependencies after copying extensions directory
RUN pnpm install --no-frozen-lockfile
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing NODE_OPTIONS memory cap

The original pnpm install at line 41 explicitly sets NODE_OPTIONS=--max-old-space-size=2048 with a comment explaining it prevents OOM kills (exit 137) on low-memory Docker hosts. This second install step omits that guard, so it can hit the same memory issue — especially because it re-resolves the full dependency graph on top of what's already installed.

Suggested change
RUN pnpm install --no-frozen-lockfile
RUN NODE_OPTIONS=--max-old-space-size=2048 pnpm install --no-frozen-lockfile
Prompt To Fix With AI
This is a comment left during a code review.
Path: Dockerfile
Line: 103

Comment:
**Missing `NODE_OPTIONS` memory cap**

The original `pnpm install` at line 41 explicitly sets `NODE_OPTIONS=--max-old-space-size=2048` with a comment explaining it prevents OOM kills (`exit 137`) on low-memory Docker hosts. This second install step omits that guard, so it can hit the same memory issue — especially because it re-resolves the full dependency graph on top of what's already installed.

```suggestion
RUN NODE_OPTIONS=--max-old-space-size=2048 pnpm install --no-frozen-lockfile
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7877d6ded9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Dockerfile Outdated
fi; \
done
# Install extension dependencies after copying extensions directory
RUN pnpm install --no-frozen-lockfile
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the second install lockfile-frozen

This new pnpm install --no-frozen-lockfile step allows dependency resolution to proceed even when a workspace manifest and pnpm-lock.yaml are out of sync (the pnpm help text says frozen mode should fail when an update is needed), which means Docker builds can silently pull unreviewed versions instead of failing fast. In practice, any stale extension package.json now produces non-reproducible images that may differ from what CI/tests validated.

Useful? React with 👍 / 👎.

Dockerfile Outdated
fi; \
done
# Install extension dependencies after copying extensions directory
RUN pnpm install --no-frozen-lockfile
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the same memory cap to the new install step

The file already documents that dependency installs can OOM on low-memory builders and mitigates that by setting NODE_OPTIONS=--max-old-space-size=2048 on the first install, but this newly added install runs without that guard. On constrained hosts, this second workspace install (which is where extension dependencies are now installed) can still be killed with exit 137 and fail the image build.

Useful? React with 👍 / 👎.

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docker Docker and sandbox tooling size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants