Skip to content

docker: make plugin_packages volume mountpoint writable#8042

Open
alazarlemma02 wants to merge 3 commits into
ether:developfrom
alazarlemma02:fix/dev/issue-8026-plugin-volume-permissions
Open

docker: make plugin_packages volume mountpoint writable#8042
alazarlemma02 wants to merge 3 commits into
ether:developfrom
alazarlemma02:fix/dev/issue-8026-plugin-volume-permissions

Conversation

@alazarlemma02

@alazarlemma02 alazarlemma02 commented Jul 10, 2026

Copy link
Copy Markdown

Summary

Fixes #8026

This PR creates src/plugin_packages in both Docker runtime stages so plugin installation works when Etherpad is started with Docker Compose.

When docker-compose.yml mounts a named volume over src/plugin_packages, Docker initializes a fresh named volume from the image mountpoint metadata. If the directory does not exist in the image, Docker creates it as root:root, which prevents the Etherpad process from creating install.lock during plugin installation.

What changed

  • Created src/plugin_packages in the Docker development runtime stage.
  • Created src/plugin_packages in the Docker production runtime stage.
  • Added a backend regression test that checks both runtime stages create the plugin package mountpoint after copying src.

Testing

  • pnpm run test
  • pnpm run lint
  • pnpm run ts-check

Notes

This keeps the fix limited to the Docker runtime image setup. It does not change plugin installation logic, public APIs, database behavior, or configuration.

Create src/plugin_packages in the development and production runtime image stages so a fresh Docker named volume is initialized with Etherpad user ownership instead of root-only ownership.

Fixes ether#8026
Replace CommonJS imports with Node.js module imports and reformat the
test to match the project's coding style. This change is purely
stylistic and does not alter the regression test's behavior.
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Docker: create writable src/plugin_packages mountpoint in runtime images

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Ensure Docker runtime images pre-create src/plugin_packages for writable named-volume
 initialization.
• Prevent plugin installs from failing when Docker creates the mountpoint as root:root.
• Add a regression test asserting both development and production stages create the directory.
Diagram

graph TD
  A["docker-compose.yml"] --> B[("Named volume")] --> C["Init from image"] --> D["Runtime stage\n(dev/prod)"] -->|"mkdir -p"| E["src/plugin_packages"] --> F["Plugin installer"] --> G["install.lock"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Track src/plugin_packages in git (e.g., .gitkeep)
  • ➕ Keeps directory creation purely in the source tree (no extra Docker RUN layer).
  • ➕ Ensures non-Docker runs also start with the directory present.
  • ➖ Git does not track empty directories; requires a sentinel file and repo policy buy-in.
  • ➖ Less explicit about ownership semantics under Docker’s volume initialization behavior.
2. Compose-level fix (init container / entrypoint chown)
  • ➕ Fixes ownership even if future image changes remove the directory.
  • ➕ Can correct existing volumes that were already initialized incorrectly.
  • ➖ More moving parts in docker-compose usage; not a self-contained image fix.
  • ➖ Potentially slower startup and requires elevated permissions (root) to chown.
3. Use install(1) / explicit chown in Dockerfile
  • ➕ Makes intended ownership/mode explicit (e.g., install -d -o etherpad -g etherpad).
  • ➕ More robust if USER context changes in future stages.
  • ➖ Slightly more verbose than mkdir -p given current stages already run as etherpad.

Recommendation: Current approach (creating src/plugin_packages inside both runtime stages) is the best minimal, image-contained fix for named-volume initialization. Consider switching to install -d -o etherpad -g etherpad if future Dockerfile refactors might change the active USER around these RUN steps.

Files changed (2) +64 / -0

Bug fix (1) +2 / -0
DockerfilePre-create src/plugin_packages in development and production runtime stages +2/-0

Pre-create src/plugin_packages in development and production runtime stages

• Adds 'RUN mkdir -p ./src/plugin_packages' after copying './src' in both the development and production runtime stages. This ensures Docker named volumes mounted at that path initialize with etherpad-owned directory metadata instead of root:root.

Dockerfile

Tests (1) +62 / -0
dockerfilePluginVolume.tsAdd regression test for Docker plugin volume mountpoint preparation +62/-0

Add regression test for Docker plugin volume mountpoint preparation

• Introduces a backend spec that parses the Dockerfile and asserts both the 'development' and 'production' stages create './src/plugin_packages' after copying './src'. This guards against regressions that would reintroduce root-owned mountpoints and break plugin installation (install.lock creation).

src/tests/backend/specs/dockerfilePluginVolume.ts

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jul 10, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Brittle Dockerfile test matching ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The new docker regression test uses indexOf() on exact Dockerfile instruction strings, so harmless
refactors (spacing, install -d instead of mkdir, added flags) will fail CI even if behavior
remains correct. This makes future Dockerfile changes unnecessarily risky.
Code

src/tests/backend/specs/dockerfilePluginVolume.ts[R41-43]

+        const srcCopy = stage.indexOf('COPY --chown=etherpad:etherpad ./src');
+        const mkdir = stage.indexOf('RUN mkdir -p ./src/plugin_packages');
+
Evidence
The test currently hard-codes exact Dockerfile strings via indexOf(), which will fail on benign
Dockerfile refactors that preserve semantics. A nearby existing Dockerfile regression test in the
same suite uses regex-based matching scoped to a stage block, demonstrating a more resilient pattern
in this repo.

src/tests/backend/specs/dockerfilePluginVolume.ts[38-58]
src/tests/backend/specs/dockerfilePnpmPin.ts[47-56]

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

## Issue description
`dockerfilePluginVolume.ts` asserts Dockerfile behavior via exact substring matches, making the test fragile to non-semantic Dockerfile edits.
### Issue Context
The intent is to ensure the runtime stages create `src/plugin_packages` after copying `src`, not to lock down the exact shell command text.
### Fix Focus Areas
- src/tests/backend/specs/dockerfilePluginVolume.ts[18-58]
### Suggested fix
- Replace the `indexOf('COPY --chown=etherpad:etherpad ./src')` and `indexOf('RUN mkdir -p ./src/plugin_packages')` checks with regex-based matches that tolerate formatting and allow equivalent commands.
- Example approach:
- Find the first match index for copying `./src` with something like `/^COPY\s+--chown=etherpad:etherpad\s+\.\/src\/?\s+\.\/src\/?/m`.
- Find a later match for creating the directory with something like `/^RUN\s+.*\b(mkdir\s+-p|install\s+-d)\s+\.\/src\/plugin_packages\b/m`.
- Keep the ordering assertion (`mkdirMatch.index > srcCopyMatch.index`).

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


Grey Divider

Qodo Logo

Comment thread src/tests/backend/specs/dockerfilePluginVolume.ts Outdated
Match Dockerfile instructions with regexes instead of exact substrings so
the regression test validates the required behavior without rejecting
harmless formatting or equivalent command changes.
@JohnMcLear

Copy link
Copy Markdown
Member

I don't know enough about docker to approve this, @SamTV12345 is better placed

@JohnMcLear
JohnMcLear requested a review from SamTV12345 July 10, 2026 09:09
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.

Failed to acquire lock for plugin installation

2 participants