From 57406dbc90e97b062c3a3d7f57b8f0b08be302b8 Mon Sep 17 00:00:00 2001 From: AiMagic5000 Date: Sun, 8 Mar 2026 13:47:59 -0700 Subject: [PATCH] fix(docker): run production server as non-root node user Switch the production stage to the built-in node user from node:lts-trixie-slim, fixing two runtime failures: 1. Claude CLI rejects --dangerously-skip-permissions when the process UID is 0, making the claude-local adapter unusable. 2. The server crashed at startup (EACCES) because /paperclip was root-owned and the process could not write logs or instance data. Changes vs the naive fix: - Use COPY --chown=node:node instead of a separate RUN chown -R, avoiding a duplicate image layer that would double the size of the /app tree in the final image. - Consolidate mkdir /paperclip + chown into the same RUN layer as the npm global install (already runs as root) to keep layer count minimal. - Add USER node before CMD so the process runs unprivileged. The VOLUME declaration comes after chown so freshly-mounted anonymous volumes inherit the correct node:node ownership. Fixes #344 --- Dockerfile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ee566109..3fe1f2b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,8 +32,10 @@ RUN test -f server/dist/index.js || (echo "ERROR: server build output missing" & FROM base AS production WORKDIR /app -COPY --from=build /app /app -RUN npm install --global --omit=dev @anthropic-ai/claude-code@latest @openai/codex@latest opencode-ai +COPY --chown=node:node --from=build /app /app +RUN npm install --global --omit=dev @anthropic-ai/claude-code@latest @openai/codex@latest opencode-ai \ + && mkdir -p /paperclip \ + && chown node:node /paperclip ENV NODE_ENV=production \ HOME=/paperclip \ @@ -49,4 +51,5 @@ ENV NODE_ENV=production \ VOLUME ["/paperclip"] EXPOSE 3100 +USER node CMD ["node", "--import", "./server/node_modules/tsx/dist/loader.mjs", "server/dist/index.js"]