Skip to content

fix: use hardlink package-import-method so Docker build works on ZFS (#7342)#7533

Merged
JohnMcLear merged 1 commit intodevelopfrom
fix/zfs-docker-build
Apr 17, 2026
Merged

fix: use hardlink package-import-method so Docker build works on ZFS (#7342)#7533
JohnMcLear merged 1 commit intodevelopfrom
fix/zfs-docker-build

Conversation

@JohnMcLear
Copy link
Copy Markdown
Member

Fixes #7342. pnpm's default package-import-method=auto ends up using copyfile + copy_file_range, which fails on ZFS with EAGAIN: resource temporarily unavailable (upstream pnpm/pnpm#7024). docker compose build therefore aborts inside RUN pnpm install on any host with a ZFS root. Force package-import-method=hardlink in the project-level .npmrc so every pnpm invocation — Dockerfile, bin/installDeps.sh, bin/installLocalPlugins.sh, bin/updatePlugins.sh — picks it up automatically instead of requiring per-command flags. Hardlinks are fast, save disk, and work on every filesystem Etherpad supports.

…ZFS (#7342)

pnpm's default \`auto\` package-import-method eventually falls through
to \`copyfile\`, which uses \`copy_file_range\`. That syscall fails on
ZFS with \`EAGAIN: resource temporarily unavailable\` (see
pnpm/pnpm#7024), so \`docker compose build\`
aborts inside the \`RUN pnpm install\` step on any host with a ZFS
root. Operators had to hand-patch every pnpm invocation in the
Dockerfile and install scripts.

Force \`package-import-method=hardlink\` in \`.npmrc\` so all pnpm
invocations (Docker build, \`bin/installDeps.sh\`,
\`bin/installLocalPlugins.sh\`, \`bin/updatePlugins.sh\`) pick up the
setting automatically. Hardlinks are fast, save disk, and work on
every filesystem Etherpad supports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Configure pnpm hardlink package-import-method for ZFS compatibility

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Configure pnpm to use hardlinks for package imports
• Resolves Docker build failures on ZFS filesystems
• Eliminates need for per-command flag workarounds
• Improves performance and disk usage across all pnpm invocations
Diagram
flowchart LR
  A["pnpm default auto mode"] -->|"uses copy_file_range"| B["Fails on ZFS"]
  B -->|"breaks docker build"| C["Build aborts"]
  D[".npmrc configuration"] -->|"sets hardlink method"| E["All pnpm commands"]
  E -->|"works on all filesystems"| F["Successful builds"]
Loading

Grey Divider

File Changes

1. .npmrc ⚙️ Configuration changes +6/-0

Add hardlink package-import-method configuration

• Added package-import-method=hardlink configuration setting
• Included detailed comments explaining ZFS compatibility issue
• References upstream pnpm issue #7024 and Etherpad issue #7342
• Documents benefits of hardlinks for performance and disk usage

.npmrc


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects bot commented Apr 17, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. ZFS pnpm hardlink untested 📘 Rule violation ☼ Reliability
Description
This PR changes pnpm behavior to fix ZFS-related Docker build failures but does not add/update any
regression test that would fail if the .npmrc setting were reverted. Without a test, the
mitigation can silently regress and reintroduce the ZFS EAGAIN install failure.
Code

.npmrc[R2-7]

+# Use hardlinks when populating node_modules instead of clone/copyfile.
+# pnpm's default "auto" mode ends up using copy_file_range which fails on
+# ZFS (https://github.com/pnpm/pnpm/issues/7024) and breaks `docker
+# compose build` on hosts with a ZFS root (#7342). Hardlinks are fast,
+# save disk, and work on every filesystem Etherpad supports.
+package-import-method=hardlink
Evidence
PR Compliance ID 6 requires a regression test for bug fixes; the diff shows only a configuration
change in .npmrc with no accompanying test additions/updates in the PR changes provided.

.npmrc[2-7]
Best Practice: Repository guidelines

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A bug fix (pnpm ZFS mitigation via `.npmrc`) was added without a regression test, so reverting/removing the setting would not be caught by automated tests.

## Issue Context
The change introduces `package-import-method=hardlink` to prevent pnpm `EAGAIN` failures on ZFS during Docker builds.

## Fix Focus Areas
- .npmrc[2-7]
- src/tests/backend-new/specs/pnpm_import_method.test.ts[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Docker ignores new pnpm config 🐞 Bug ≡ Correctness
Description
The new package-import-method=hardlink setting is not applied to pnpm commands run by
bin/installDeps.sh/bin/installLocalPlugins.sh during Docker builds because .npmrc is never
copied into the relevant Docker build stages. This can leave Docker builds on ZFS still using pnpm’s
default import method and failing despite this PR.
Code

.npmrc[R2-7]

+# Use hardlinks when populating node_modules instead of clone/copyfile.
+# pnpm's default "auto" mode ends up using copy_file_range which fails on
+# ZFS (https://github.com/pnpm/pnpm/issues/7024) and breaks `docker
+# compose build` on hosts with a ZFS root (#7342). Hardlinks are fast,
+# save disk, and work on every filesystem Etherpad supports.
+package-import-method=hardlink
Evidence
Although .npmrc is added at the repo root, the Dockerfile’s build stage only copies a subset of
files (settings/var/bin/pnpm-workspace.yaml/package.json) and then later runs scripts that invoke
pnpm; because .npmrc is not copied, those pnpm invocations cannot read the new config and will
fall back to defaults.

Dockerfile[121-127]
Dockerfile[154-161]
Dockerfile[174-191]
bin/installDeps.sh[36-43]
bin/installLocalPlugins.sh[36-43]
.npmrc[1-7]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The PR relies on a repo-level `.npmrc` to force `package-import-method=hardlink`, but the Docker build stages that execute `bin/installDeps.sh` and `bin/installLocalPlugins.sh` do not include `.npmrc`. As a result, pnpm in those stages will not pick up the new config and can still fail on ZFS.

### Issue Context
- `.npmrc` is present in the repo and will be present in stages that `COPY . .`, but the main `build` stage uses selective `COPY` instructions and omits `.npmrc`.
- The Dockerfile later runs scripts that invoke pnpm; those invocations need the same config to fully address #7342.

### Fix Focus Areas
- Dockerfile[121-127]
- Dockerfile[154-161]
- Dockerfile[174-191]

### Suggested change
In the Dockerfile `build` stage, add `.npmrc` to the files copied into the image (e.g., alongside `pnpm-workspace.yaml` and `package.json`) before any `RUN ...install...` steps that execute pnpm. This ensures `package-import-method=hardlink` applies consistently to all pnpm invocations during the Docker build.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread .npmrc
Comment on lines +2 to +7
# Use hardlinks when populating node_modules instead of clone/copyfile.
# pnpm's default "auto" mode ends up using copy_file_range which fails on
# ZFS (https://github.com/pnpm/pnpm/issues/7024) and breaks `docker
# compose build` on hosts with a ZFS root (#7342). Hardlinks are fast,
# save disk, and work on every filesystem Etherpad supports.
package-import-method=hardlink
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Zfs pnpm hardlink untested 📘 Rule violation ☼ Reliability

This PR changes pnpm behavior to fix ZFS-related Docker build failures but does not add/update any
regression test that would fail if the .npmrc setting were reverted. Without a test, the
mitigation can silently regress and reintroduce the ZFS EAGAIN install failure.
Agent Prompt
## Issue description
A bug fix (pnpm ZFS mitigation via `.npmrc`) was added without a regression test, so reverting/removing the setting would not be caught by automated tests.

## Issue Context
The change introduces `package-import-method=hardlink` to prevent pnpm `EAGAIN` failures on ZFS during Docker builds.

## Fix Focus Areas
- .npmrc[2-7]
- src/tests/backend-new/specs/pnpm_import_method.test.ts[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread .npmrc
Comment on lines +2 to +7
# Use hardlinks when populating node_modules instead of clone/copyfile.
# pnpm's default "auto" mode ends up using copy_file_range which fails on
# ZFS (https://github.com/pnpm/pnpm/issues/7024) and breaks `docker
# compose build` on hosts with a ZFS root (#7342). Hardlinks are fast,
# save disk, and work on every filesystem Etherpad supports.
package-import-method=hardlink
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Docker ignores new pnpm config 🐞 Bug ≡ Correctness

The new package-import-method=hardlink setting is not applied to pnpm commands run by
bin/installDeps.sh/bin/installLocalPlugins.sh during Docker builds because .npmrc is never
copied into the relevant Docker build stages. This can leave Docker builds on ZFS still using pnpm’s
default import method and failing despite this PR.
Agent Prompt
### Issue description
The PR relies on a repo-level `.npmrc` to force `package-import-method=hardlink`, but the Docker build stages that execute `bin/installDeps.sh` and `bin/installLocalPlugins.sh` do not include `.npmrc`. As a result, pnpm in those stages will not pick up the new config and can still fail on ZFS.

### Issue Context
- `.npmrc` is present in the repo and will be present in stages that `COPY . .`, but the main `build` stage uses selective `COPY` instructions and omits `.npmrc`.
- The Dockerfile later runs scripts that invoke pnpm; those invocations need the same config to fully address #7342.

### Fix Focus Areas
- Dockerfile[121-127]
- Dockerfile[154-161]
- Dockerfile[174-191]

### Suggested change
In the Dockerfile `build` stage, add `.npmrc` to the files copied into the image (e.g., alongside `pnpm-workspace.yaml` and `package.json`) before any `RUN ...install...` steps that execute pnpm. This ensures `package-import-method=hardlink` applies consistently to all pnpm invocations during the Docker build.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@JohnMcLear JohnMcLear merged commit aed5424 into develop Apr 17, 2026
36 checks passed
@JohnMcLear JohnMcLear deleted the fix/zfs-docker-build branch April 17, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Building Docker image on ZFS file system fails

1 participant