From f8686dda1043b4003efe0d06afce2aea68d814aa Mon Sep 17 00:00:00 2001 From: Alazar Keneni <112463751+alazarlemma02@users.noreply.github.com> Date: Mon, 27 Jul 2026 22:44:30 +0300 Subject: [PATCH] docker: make `plugin_packages` volume mountpoint writable (#8042) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docker: prepare plugin volume mountpoint 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 #8026 * tests: align docker plugin volume regression test with project style 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. * tests: make docker plugin volume test less brittle 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. * docker: explain the plugin_packages mountpoint, drop the Dockerfile-text test The reason the two `mkdir`s exist is not obvious from the Dockerfile, so state it where the next reader will be: a named volume inherits the mountpoint's ownership from the image, and USER is already etherpad at that point. Removes dockerfilePluginVolume.ts. It asserted that the Dockerfile *text* contains `mkdir -p ./src/plugin_packages` after the `COPY ./src` line — it fails when the Dockerfile is refactored (a `.gitkeep`, a `VOLUME`, a different order all keep the behaviour intact) and it cannot fail when the actual bug returns, since it never inspects a built image. The build-test job already builds both runtime stages. Co-Authored-By: Claude Opus 5 (1M context) --------- Co-authored-by: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) --- Dockerfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Dockerfile b/Dockerfile index be7a201ca..f0ad8351c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -171,6 +171,12 @@ ARG ETHERPAD_GITHUB_PLUGINS= COPY --chown=etherpad:etherpad ./src/ ./src/ COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/templates/admin ./src/templates/admin COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/static/oidc ./src/static/oidc +# docker-compose mounts a named volume over src/plugin_packages. Docker seeds a +# fresh named volume from the mountpoint in the image, so the directory has to +# exist here (owned by etherpad, since USER is already etherpad) — otherwise +# Docker creates it root:root and plugin installs cannot write install.lock. +# See ether/etherpad#8026. +RUN mkdir -p ./src/plugin_packages COPY --chown=etherpad:etherpad ./local_plugin[s] ./local_plugins/ @@ -203,6 +209,12 @@ RUN printf 'packages:\n - src\n - bin\nonlyBuiltDependencies:\n - esbuild\nig COPY --chown=etherpad:etherpad ./src ./src COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/templates/admin ./src/templates/admin COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/static/oidc ./src/static/oidc +# docker-compose mounts a named volume over src/plugin_packages. Docker seeds a +# fresh named volume from the mountpoint in the image, so the directory has to +# exist here (owned by etherpad, since USER is already etherpad) — otherwise +# Docker creates it root:root and plugin installs cannot write install.lock. +# See ether/etherpad#8026. +RUN mkdir -p ./src/plugin_packages COPY --chown=etherpad:etherpad ./local_plugin[s] ./local_plugins/