Skip to content

fix(docker): let non-root backend create its uploads dir (multer 2 eager mkdir) - #114

Merged
pmigueld merged 1 commit into
developfrom
fix/backend-uploads-dir-perms
Aug 4, 2026
Merged

fix(docker): let non-root backend create its uploads dir (multer 2 eager mkdir)#114
pmigueld merged 1 commit into
developfrom
fix/backend-uploads-dir-perms

Conversation

@pmigueld

@pmigueld pmigueld commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Staging sync-server crash-looped (16× restarts) after the volume/init-script fix (#113) cleared the postgres issue. Real cause, from the container log:

EACCES: permission denied, mkdir '/app/uploads'
  at new DiskStorage (multer@2.2.0/storage/disk.js:20)
  at createOpenSppFieldRoutes (dist/routes/opensppFieldRoutes.js:260)

Two recent changes collide:

  • multer 2.x eagerly mkdirSyncs a diskStorage destination at route-construction (startup), where multer 1.x did not.
  • the backend container runs as the non-root node user.

WORKDIR /app is created root-owned, and COPY --chown=node:node only chowns the copied contents — not the /app directory itself. So node can't create /app/uploads (the OpenSPP-field route's upload dir, path.resolve(process.cwd(), "uploads")) → uncaught exception → crash loop. DB init succeeds first, which is why it looked DB-related.

Fix

In the backend stage of docker/Dockerfile, before USER node:

RUN mkdir -p /app/uploads && chown node:node /app /app/uploads

Gives node ownership of the workdir and pre-creates the uploads dir (multer's recursive mkdir then no-ops).

Scope / impact

Affects any fresh deploy of the backend image — including production / v2.1.0 (same Dockerfile + multer 2 + non-root). Recommend cherry-picking to main (or a 2.1.1) after this merges. Verified by redeploying staging.

🤖 Generated with Claude Code

@pmigueld
pmigueld merged commit 15d50a9 into develop Aug 4, 2026
9 checks passed
@pmigueld
pmigueld deleted the fix/backend-uploads-dir-perms branch August 5, 2026 04:38
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.

1 participant