From 42368f84bf67b3e00537a7c6ad56d594ab79bb0d Mon Sep 17 00:00:00 2001 From: 0xjjjjjj <0xjjjjjj@users.noreply.github.com> Date: Sat, 7 Mar 2026 20:38:09 -0800 Subject: [PATCH 1/2] perf: replace chown -R with COPY --chown in both Dockerfiles Move user/group creation before COPY statements so --chown flag can set ownership at copy time, avoiding the slow recursive chown on overlay2 filesystems (docker/for-linux#388). Co-Authored-By: Claude Opus 4.6 --- backend/Dockerfile | 19 ++++++++++--------- frontend/Dockerfile | 15 ++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 364fc1a6..d7cf1401 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -29,26 +29,27 @@ RUN uv sync --frozen --no-dev # --- runtime --- FROM base AS runtime +# Create non-root user before COPY so --chown can reference it. +# Using COPY --chown avoids a slow recursive chown on overlay2 (docker/for-linux#388). +RUN groupadd --system appgroup && useradd --system --gid appgroup --create-home appuser + # Copy virtual environment from deps stage -COPY --from=deps /app/.venv /app/.venv +COPY --from=deps --chown=appuser:appgroup /app/.venv /app/.venv ENV PATH="/app/.venv/bin:${PATH}" # Copy app source -COPY backend/migrations ./migrations -COPY backend/alembic.ini ./alembic.ini -COPY backend/app ./app +COPY --chown=appuser:appgroup backend/migrations ./migrations +COPY --chown=appuser:appgroup backend/alembic.ini ./alembic.ini +COPY --chown=appuser:appgroup backend/app ./app # Copy provisioning templates. # In-repo these live at `backend/templates/`; runtime path is `/app/templates`. -COPY backend/templates ./templates +COPY --chown=appuser:appgroup backend/templates ./templates # Copy worker scripts. # In-repo these live at `scripts/`; runtime path is `/app/scripts`. -COPY scripts ./scripts +COPY --chown=appuser:appgroup scripts ./scripts -# Run as non-root user -RUN groupadd --system appgroup && useradd --system --gid appgroup appuser \ - && chown -R appuser:appgroup /app USER appuser # Default API port diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 61293512..3869779d 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -31,16 +31,17 @@ ARG NEXT_PUBLIC_AUTH_MODE ENV NEXT_PUBLIC_API_URL=auto ENV NEXT_PUBLIC_AUTH_MODE=${NEXT_PUBLIC_AUTH_MODE} -COPY --from=builder /app/.next ./.next +# Create non-root user before COPY so --chown can reference it. +# Using COPY --chown avoids a slow recursive chown on overlay2 (docker/for-linux#388). +RUN addgroup -S appgroup && adduser -S -G appgroup appuser + +COPY --from=builder --chown=appuser:appgroup /app/.next ./.next # `public/` is optional in Next.js apps; repo may not have it. # Avoid failing the build when the directory is absent. -COPY --from=builder /app/package.json ./package.json -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/next.config.ts ./next.config.ts +COPY --from=builder --chown=appuser:appgroup /app/package.json ./package.json +COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules +COPY --from=builder --chown=appuser:appgroup /app/next.config.ts ./next.config.ts -# Run as non-root user -RUN addgroup -S appgroup && adduser -S -G appgroup appuser \ - && chown -R appuser:appgroup /app USER appuser EXPOSE 3000 From 9396be6fc011fdcd31ac2c9ecba51eb500baafd1 Mon Sep 17 00:00:00 2001 From: 0xjjjjjj <0xjjjjjj@users.noreply.github.com> Date: Sat, 7 Mar 2026 20:45:25 -0800 Subject: [PATCH 2/2] fix: chown /app directory after user creation Ensure the /app WORKDIR itself is owned by appuser (not just copied files), preventing runtime failures if the app writes to /app directly. Co-Authored-By: Claude Opus 4.6 --- backend/Dockerfile | 3 ++- frontend/Dockerfile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index d7cf1401..a8e87052 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -31,7 +31,8 @@ FROM base AS runtime # Create non-root user before COPY so --chown can reference it. # Using COPY --chown avoids a slow recursive chown on overlay2 (docker/for-linux#388). -RUN groupadd --system appgroup && useradd --system --gid appgroup --create-home appuser +RUN groupadd --system appgroup && useradd --system --gid appgroup --create-home appuser \ + && chown appuser:appgroup /app # Copy virtual environment from deps stage COPY --from=deps --chown=appuser:appgroup /app/.venv /app/.venv diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 3869779d..09bf6811 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -33,7 +33,8 @@ ENV NEXT_PUBLIC_AUTH_MODE=${NEXT_PUBLIC_AUTH_MODE} # Create non-root user before COPY so --chown can reference it. # Using COPY --chown avoids a slow recursive chown on overlay2 (docker/for-linux#388). -RUN addgroup -S appgroup && adduser -S -G appgroup appuser +RUN addgroup -S appgroup && adduser -S -G appgroup appuser \ + && chown appuser:appgroup /app COPY --from=builder --chown=appuser:appgroup /app/.next ./.next # `public/` is optional in Next.js apps; repo may not have it.