Issue #245978 feat: Provider BE - Docker Security Hotspot fixes#131
Issue #245978 feat: Provider BE - Docker Security Hotspot fixes#131rajnishdargan wants to merge 9 commits intoPSMRI:mainfrom
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdded a Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev
participant Docker as Docker build
participant Builder as Builder (node:20-alpine)
participant Runner as Runner (node:20-alpine)
participant Container as App Container
Dev->>Docker: docker build .
Docker->>Builder: execute build stage
note right of Builder #e8f5e9: npm ci (builder)\nnpx prisma generate\nnpm run build\nproduce dist/ and prisma/
Builder-->>Docker: build artifacts available
Docker->>Runner: copy runtime artifacts (dist/, prisma/, node_modules/.prisma/, node_modules/@prisma/client/)
note right of Runner #fff3e0: install runtime deps (npm ci --omit=dev)\ncreate appuser/appgroup\nset ownership & perms\nEXPOSE 7000
Runner-->>Docker: final image produced
Dev->>Container: docker run -p 7000:7000 image
Container->>Container: start as non-root user -> node dist/main.js\nlisten on 0.0.0.0:7000
Container-->>Dev: service available on port 7000
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Cache: Disabled due to data retention organization setting Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Dockerfile (1)
1-35: Use a multi-stage build to drop dev deps and avoid shipping sourceCurrent image keeps devDependencies and src, increasing attack surface and size. Switch to multi-stage, prune dev deps, and run as non-root in the final stage.
Apply:
-FROM node:20-alpine AS dependencies -# Create app group and user with specific UID/GID -RUN addgroup -g 1001 -S appgroup && \ - adduser -S appuser -u 1001 -G appgroup -# Create and set ownership of app directory -RUN mkdir -p /app && chown -R appuser:appgroup /app -WORKDIR /app -# Install all dependencies as root first (including dev dependencies for Prisma) -COPY --chown=appuser:appgroup package*.json ./ -RUN npm ci && npm cache clean --force -# Copy application files with proper ownership -COPY --chown=appuser:appgroup prisma/ ./prisma/ -COPY --chown=appuser:appgroup src/ ./src/ -COPY --chown=appuser:appgroup nest-cli.json ./ -COPY --chown=appuser:appgroup tsconfig*.json ./ -COPY --chown=appuser:appgroup eslint.config.mjs ./ -# Optional check to confirm schema exists, generate Prisma client and build project as root -RUN ls -la prisma/schema.prisma && \ - npx prisma generate && \ - npm run build -# Switch to non-root user for runtime -USER appuser -# Expose the correct port for your application -EXPOSE 7000 -CMD ["npm", "run", "start:prod"] +FROM node:20-alpine AS builder +WORKDIR /app +# Install deps (dev included for build) +COPY package*.json ./ +RUN npm ci --no-audit --no-fund && npm cache clean --force +# Copy sources +COPY prisma/ ./prisma/ +COPY tsconfig*.json ./ +COPY nest-cli.json ./ +COPY src/ ./src/ +# Generate Prisma client and build +RUN test -f prisma/schema.prisma && npx prisma generate && npm run build +# Prune devDependencies for runtime +RUN npm prune --omit=dev + +FROM node:20-alpine AS runner +ENV NODE_ENV=production +WORKDIR /app +# Create non-root user +RUN addgroup -g 1001 -S appgroup && adduser -S -u 1001 -G appgroup -s /sbin/nologin -h /home/appuser appuser \ + && mkdir -p /app && chown -R appuser:appgroup /app +# Copy minimal runtime assets +COPY --from=builder /app/package*.json ./ +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/dist ./dist +USER appuser +EXPOSE 7000 +# If start:prod calls `node dist/main.js`, keep as-is. Otherwise consider: CMD ["node","dist/main.js"] +CMD ["npm", "run", "start:prod"]
🧹 Nitpick comments (2)
Dockerfile (2)
12-15: Supply-chain hardening for npm ci
Skip audit/fund noise; consider ignoring lifecycle scripts only if you keep an explicitprisma generate.Apply:
-RUN npm ci && npm cache clean --force +RUN npm ci --no-audit --no-fund && npm cache clean --force +# If your deps don't rely on install scripts, you can add: --ignore-scripts +# and keep the explicit `npx prisma generate` later.
31-35: Add a HEALTHCHECK (optional)
If you expose a health endpoint, wire it for container health to aid orchestrators.Example:
EXPOSE 7000 +HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \ + CMD node -e "require('http').get('http://127.0.0.1:7000/health', r => process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))" CMD ["npm", "run", "start:prod"]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (3)
.dockerignore(1 hunks)Dockerfile(1 hunks)src/app.service.ts(1 hunks)
🔇 Additional comments (1)
Dockerfile (1)
34-34: No changes required for Dockerfile CMD
Thestart:prodscript is defined asnode dist/mainand doesn’t rely on dev-only tools, so leavingCMD ["npm", "run", "start:prod"]is appropriate.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
Dockerfile (1)
4-5: Use a non-login shell and set a home for the system user.Harden the system account; avoid interactive shells and provide a writable HOME for npm logs/cache.
-RUN addgroup -g 1001 -S appgroup && \ - adduser -S appuser -u 1001 -G appgroup +RUN addgroup -g 1001 -S appgroup && \ + adduser -S appuser -u 1001 -G appgroup -s /sbin/nologin -h /home/appuserIf
/sbin/nologinis unavailable, use/bin/false.
🧹 Nitpick comments (4)
Dockerfile (4)
8-8: Avoid redundant chown; prefer COPY --chown to reduce layers.You first chown
/appto appuser, then later chown everything to root:appgroup. Drop the early chown and use--chownon COPY.-RUN mkdir -p /app && chown -R appuser:appgroup /app +RUN mkdir -p /app @@ -COPY prisma/ ./prisma/ -COPY src/ ./src/ -COPY nest-cli.json ./ -COPY tsconfig*.json ./ -COPY eslint.config.mjs ./ +COPY --chown=root:appgroup prisma/ ./prisma/ +COPY --chown=root:appgroup src/ ./src/ +COPY --chown=root:appgroup nest-cli.json ./ +COPY --chown=root:appgroup tsconfig*.json ./ +COPY --chown=root:appgroup eslint.config.mjs ./Also applies to: 24-34
25-25: Remove debugls -lain build step.Keeps layers clean and reproducible.
-RUN ls -la prisma/schema.prisma && \ +RUN \ npx prisma generate && \ npm run build && \
36-42: Prefer running node directly; set npm cache to writable dir if you keep npm.
npm runcan write to $HOME/.npm; without a HOME it may warn/fail. Either run node directly (preferred) or set cache.-USER appuser -EXPOSE 7000 -CMD ["npm", "run", "start:prod"] +ENV NPM_CONFIG_CACHE=/tmp/.npm +USER appuser +EXPOSE 7000 +# or: CMD ["node","dist/main.js"] +CMD ["npm","run","start:prod"]
1-1: Alpine + Prisma: ensure required runtime libs.On Alpine, Prisma engines may need
libc6-compat(and oftenopenssl) at runtime. Install in the final stage.-FROM node:20-alpine AS dependencies +FROM node:20-alpine AS dependencies +RUN apk add --no-cache libc6-compat opensslAlso applies to: 24-27
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
Dockerfile(1 hunks)
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/app.e2e-spec.ts (1)
10-17: Close the Nest app to avoid open-handle leaks; prefer beforeAll/afterAll.Tests may hang or leak resources without
app.close(). Initialize once, tear down once.- beforeEach(async () => { + beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); await app.init(); - }); + }); + + afterAll(async () => { + await app.close(); + });
♻️ Duplicate comments (2)
src/app.controller.spec.ts (2)
18-19: Ensure consistency with e2e test and service return.Same potential
<br>mismatch risk as noted in e2e spec; verify the exact string once.
18-19: Optional: use a shared constant for the message.Reference a single source (e.g., tests/utils/constants.ts) to avoid drift between unit and e2e tests.
🧹 Nitpick comments (2)
test/app.e2e-spec.ts (2)
8-8: Nit: Drop the supertest App generic.
INestApplication’s default generic is fine and avoids coupling to supertest types.- let app: INestApplication<App>; + let app: INestApplication;
23-23: De-duplicate the expected message across tests.Consider a shared test constant (e.g., tests/utils/constants.ts) to keep expectations in sync.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (3)
Dockerfile(1 hunks)src/app.controller.spec.ts(1 hunks)test/app.e2e-spec.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- Dockerfile
🔇 Additional comments (3)
test/app.e2e-spec.ts (2)
23-23: Expectation string updated correctly.Matches the new greeting.
23-23: AppService.getHello() return value matches test expectation
The service returns'Strapi Provider MW Backend!!'(no<br>), so the test’s.expect('Strapi Provider MW Backend!!')is correct.src/app.controller.spec.ts (1)
18-20: Unit test expectation updated correctly.Aligned with the new greeting from
AppService.getHello().
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.dockerignore (1)
14-16: Harden ignore rules for package manager RC files (wildcards too)Include wildcard variants to catch workspace/local overrides.
.npmrc .yarnrc .pnpmrc +*.npmrc +*.yarnrc +*.pnpmrcDockerfile (1)
1-41: Adopt a proper multi-stage build; ship only prod deps; set NODE_ENV; add initReduces attack surface and image size; keeps dev toolchain out of runtime.
-FROM node:20-alpine AS dependencies - -# Create app group and user with specific UID/GID, and set up app directory -RUN addgroup -g 1001 -S appgroup && \ - adduser -S appuser -u 1001 -G appgroup -s /sbin/nologin -h /home/appuser && \ - mkdir -p /app && chown -R appuser:appgroup /app - -WORKDIR /app - -# Copy package files as root without giving write permissions to appuser -COPY package*.json ./ -RUN chown root:appgroup package*.json && chmod 644 package*.json && \ - npm ci --ignore-scripts && npm cache clean --force - -# Copy application files as root with read-only permissions -COPY prisma/ ./prisma/ -COPY src/ ./src/ -COPY nest-cli.json ./ -COPY tsconfig*.json ./ -COPY eslint.config.mjs ./ - -# Generate Prisma client and build project first (while files are still writable) -RUN ls -la prisma/schema.prisma && \ - npx prisma generate && \ - npm run build && \ - chown -R root:appgroup . && \ - chmod -R o-rwx . && \ - find . -type f -exec chmod g-w {} \; && \ - find . -type d -exec chmod g-w {} \; && \ - mkdir -p /app/logs /app/temp && \ - chown appuser:appgroup /app/logs /app/temp && \ - chmod 755 /app/logs /app/temp - -# Switch to non-root user for runtime -USER appuser - -# Expose the correct port for your application -EXPOSE 7000 - -CMD ["npm", "run", "start:prod"] +FROM node:20-alpine AS builder +RUN apk add --no-cache python3 make g++ libc6-compat +WORKDIR /app +COPY package*.json ./ +# Install all deps for build (dev+prod) +RUN npm ci +COPY prisma/ ./prisma/ +COPY src/ ./src/ +COPY nest-cli.json ./ +COPY tsconfig*.json ./ +COPY eslint.config.mjs ./ +# Generate Prisma client and build +RUN npx prisma generate && npm run build +# Prune to production deps only to reduce size +RUN npm prune --omit=dev && npm cache clean --force + +FROM node:20-alpine AS runner +ENV NODE_ENV=production +# Minimal init for proper signal handling +RUN apk add --no-cache tini +# Create app user/group +RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup -s /sbin/nologin -h /home/appuser +WORKDIR /app +# Copy pruned node_modules and runtime artifacts +COPY --from=builder --chown=root:appgroup /app/node_modules ./node_modules +COPY --from=builder --chown=root:appgroup /app/dist ./dist +COPY --from=builder --chown=root:appgroup /app/prisma ./prisma +COPY --from=builder --chown=root:appgroup /app/package*.json ./ +# Tighten perms (preserve exec bits) +RUN chown -R root:appgroup . && chmod -R o-rwx . && \ + find . -type f -exec chmod g-w {} \; && find . -type d -exec chmod g-w {} \; && \ + mkdir -p /app/logs /app/temp && chown appuser:appgroup /app/logs /app/temp && chmod 755 /app/logs /app/temp +USER appuser +EXPOSE 7000 +ENTRYPOINT ["/sbin/tini","--"] +CMD ["node","dist/main.js"]
🧹 Nitpick comments (2)
.dockerignore (1)
79-88: Ignore common cloud credentials directoriesPrevents accidental leakage of local cloud creds into build context.
# Keys/credentials *.pem *.key *.p12 *.pfx *.crt id_rsa* id_ed25519* .ssh/ +.aws/ +.kube/ +.azure/ +.config/gcloud/ +.git-credentials +.gitconfigDockerfile (1)
22-25: Remove build-time debug lsReduces noise and doesn’t add value in final image layers.
-RUN ls -la prisma/schema.prisma && \ - npx prisma generate && \ +RUN npx prisma generate && \
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (3)
.dockerignore(1 hunks)Dockerfile(1 hunks)src/main.ts(1 hunks)
🔇 Additional comments (1)
Dockerfile (1)
37-41: No Dockerfile CMD changes needed
Verifiedpackage.jsonincludes astart:prodscript, soCMD ["npm", "run", "start:prod"]will work as intended.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
Dockerfile (1)
16-16: Non-login runtime user — good hardeningUsing a dedicated user with nologin and home dir is the right call.
🧹 Nitpick comments (2)
src/main.ts (1)
53-54: Handle PORT=0 and validate range (minor)Current fallback treats 0 as falsy. Preserve 0 (ephemeral) and guard invalid values.
- const port = parseInt(process.env.PORT ?? '', 10) || 7000; + const p = Number(process.env.PORT); + const port = Number.isFinite(p) && p >= 0 && p <= 65535 ? p : 7000;Dockerfile (1)
24-28: Adopt tini as PID 1 for proper signal handling and zombie reaping (optional)Improves shutdown on SIGTERM in containers.
# runtime dirs RUN mkdir -p /app/logs /app/temp && chown appuser:appgroup /app/logs /app/temp && chmod 755 /app/logs /app/temp +RUN apk add --no-cache tini USER appuser EXPOSE 7000 +ENTRYPOINT ["/sbin/tini","--"] CMD ["node", "dist/main.js"]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (2)
Dockerfile(1 hunks)src/main.ts(1 hunks)
🔇 Additional comments (2)
src/main.ts (1)
52-54: Port binding and 0.0.0.0 default look goodBinding explicitly to 0.0.0.0 and defaulting to 7000 improves container reachability and keeps Dockerfile/app consistent.
Dockerfile (1)
27-28: Port alignment with app (7000) — consistentEXPOSE matches src/main.ts default/bind. Good.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
Dockerfile (3)
5-5: Remove --ignore-scripts; it breaks Prisma/native deps generation.Lifecycle hooks are needed for @prisma/client and other native modules. Running with --ignore-scripts risks a broken runtime even if the builder ran prisma generate.
Apply:
-RUN npm ci --ignore-scripts +RUN npm ci-RUN chmod 644 package*.json && npm ci --omit=dev --ignore-scripts && npm cache clean --force +RUN chmod 644 package*.json && npm ci --omit=dev && npm cache clean --forceAlso applies to: 19-19
21-23: Ensure Prisma client artifacts are present at runtime.Right now only engines (.prisma) are copied; the generated @prisma/client is not. Without postinstall (currently disabled) or copying @prisma/client, Prisma will fail at runtime.
Pick one:
A) Allow scripts (preferred; see prior comment) and don’t copy engines:
-COPY --from=builder --chown=root:appgroup /app/node_modules/.prisma/ ./node_modules/.prisma/B) Keep scripts disabled (not recommended) and copy the generated client too:
+COPY --from=builder --chown=root:appgroup /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/
24-26: Don’t strip execute bits; breaks Prisma engines and any binaries.
chmod -R 644 prisma/ dist/ node_modules/.prisma/removes x-bits from engine binaries. This will crash at startup.Safer perms (preserve executables):
-RUN chmod -R 644 prisma/ dist/ node_modules/.prisma/ && \ - find prisma/ dist/ node_modules/.prisma/ -type d -exec chmod 755 {} \; && \ +RUN find prisma/ dist/ -type d -exec chmod 755 {} \; && \ + find prisma/ dist/ -type f -exec chmod g-w {} \; && \ mkdir -p /app/logs /app/temp && chown appuser:appgroup /app/logs /app/temp && chmod 755 /app/logs /app/tempIf you keep copying
.prisma/, exclude it from chmod entirely.
🧹 Nitpick comments (2)
Dockerfile (2)
18-19: Minor: avoid chmod of package.json; let npm manage perms.The explicit 644 is unnecessary; drop for simplicity.
-COPY --chown=root:appgroup package*.json ./ -RUN chmod 644 package*.json && npm ci --omit=dev && npm cache clean --force +COPY --chown=root:appgroup package*.json ./ +RUN npm ci --omit=dev && npm cache clean --force
2-2: Optional: install build tooling only when needed and cache npm.Use a virtual package for build deps and leverage Dockerfile cache mounts for faster builds.
Example:
-RUN apk add --no-cache g++ libc6-compat make python3 +RUN apk add --no-cache g++ libc6-compat make python3 +# or: RUN --mount=type=cache,target=/root/.npm npm ci
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
Dockerfile(1 hunks)
🔇 Additional comments (5)
Dockerfile (5)
16-16: Non-root user with nologin looks good.
Hardened user setup is correct and follows least-privilege.
11-11: Confirm builder can run prisma generate.With
npm cinow running scripts, this is fine. If you ever reintroduce--ignore-scripts, some dev deps requiring builds may fail here.Would you like a quick check script to scan package.json for native deps that typically need install scripts?
21-21: Verify need to ship prisma/schema in runtime.If you rely on @prisma/client postinstall in runner, keeping
prisma/is necessary; otherwise, drop it to reduce leakage.
27-27: USER appuser is correct.Least-privilege runtime is enforced.
28-29: Port exposure matches application listen port. Verified thatsrc/main.tsdefaults to port 7000, soEXPOSE 7000and theCMDare correctly aligned.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
Dockerfile (1)
19-19: Avoid --ignore-scripts in runner; risk breaking native deps and Prisma hooks.Either rely on copied artifacts fully or allow lifecycle scripts to run.
Apply:
-RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force +RUN npm ci --omit=dev && npm cache clean --forceTo verify no prod deps need install scripts, run:
#!/bin/bash set -euo pipefail python - <<'PY' import json,sys p=json.load(open("package.json")) deps={} for k in ("dependencies","optionalDependencies"): deps.update(p.get(k) or {}) needs={"prisma","@prisma/client","bcrypt","argon2","sharp","canvas","better-sqlite3","sqlite3","node-sass","sass-embedded"} hit=sorted(set(deps).intersection(needs)) print("deps_requiring_scripts:", ", ".join(hit) if hit else "none") PY
🧹 Nitpick comments (2)
Dockerfile (2)
21-24: Avoid forcing 0755 on copied files.--chmod=755 marks all files executable unnecessarily and complicates later permission fixes.
Apply:
-COPY --chown=root:appgroup --chmod=755 prisma/ ./prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/dist/ ./dist/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/.prisma/ ./node_modules/.prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/ +COPY --chown=root:appgroup prisma/ ./prisma/ +COPY --from=builder --chown=root:appgroup /app/dist/ ./dist/ +COPY --from=builder --chown=root:appgroup /app/node_modules/.prisma/ ./node_modules/.prisma/ +COPY --from=builder --chown=root:appgroup /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/
28-29: Consider adding a liveness probe and tini for production
Bind to 0.0.0.0:7000 is confirmed in src/main.ts. To improve container reliability, install tini and add a Docker HEALTHCHECK:FROM node:20-alpine AS runner ENV NODE_ENV=production +RUN apk add --no-cache tini USER appuser EXPOSE 7000 +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD wget -qO- http://127.0.0.1:7000/health || exit 1 -CMD ["node", "dist/main.js"] +ENTRYPOINT ["/sbin/tini","--"] +CMD ["node", "dist/main.js"]Adjust the health endpoint path as needed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
Dockerfile(1 hunks)
🔇 Additional comments (2)
Dockerfile (2)
1-12: Multi-stage Alpine build and CI flow look solid.Builder stage is clean and minimal; good use of npm ci and prisma generate before build.
16-16: Non-root, nologin user: LGTM.Good hardening with explicit UID/GID and nologin shell.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
Dockerfile (4)
16-16: Good hardening: non-root user with nologin shell.User creation with /sbin/nologin and explicit UID/GID looks solid.
5-5: Remove --ignore-scripts in builder; it breaks deps needing lifecycle hooks (incl. Prisma).Lifecycle scripts are needed for native/build-time deps; skipping them is risky even if you later run
prisma generate.Apply:
-RUN npm ci --ignore-scripts +RUN npm ci
19-19: Do not use --ignore-scripts in the runner; allow postinstall hooks.Other prod deps may require scripts; you’re already running as non-root, so keep scripts enabled and still omit devDeps.
Apply:
-RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force +RUN npm ci --omit=dev && npm cache clean --force
21-26: Danger: stripping execute bits from Prisma engines; also redundant perms churn.
find ... -exec chmod 644over.prismaand@prisma/clientremoves x-bits required by Prisma binaries → runtime crash.- You first
COPY --chmod=755then immediately downgrade to 644; pick one consistent, safe policy.Apply one of the safe fixes (preferred: don’t touch node_modules and only chmod non-exec files you control):
-COPY --chown=root:appgroup --chmod=755 prisma/ ./prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/dist/ ./dist/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/.prisma/ ./node_modules/.prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/ -RUN find prisma/ dist/ node_modules/.prisma/ node_modules/@prisma/client/ -type f -exec chmod 644 {} \; && \ - mkdir -p /app/logs /app/temp && chown appuser:appgroup /app/logs /app/temp && chmod 755 /app/logs /app/temp +COPY --chown=root:appgroup prisma/ ./prisma/ +COPY --from=builder --chown=root:appgroup /app/dist/ ./dist/ +COPY --from=builder --chown=root:appgroup /app/node_modules/.prisma/ ./node_modules/.prisma/ +COPY --from=builder --chown=root:appgroup /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/ +RUN find prisma/ dist/ -type f ! -perm /111 -exec chmod 644 {} \; && \ + mkdir -p /app/logs /app/temp && chown appuser:appgroup /app/logs /app/temp && chmod 755 /app/logs /app/temp
🧹 Nitpick comments (3)
Dockerfile (3)
1-1: Optional: pin base image by digest for supply‑chain stability.Use an immutable digest to avoid surprise upgrades.
Apply:
-FROM node:20-alpine AS builder +FROM node:20-alpine@sha256:<digest> AS builder(and same for runner).
13-14: Optional: add HEALTHCHECK and OCI labels.Improves operability and provenance in registries.
Example:
FROM node:20-alpine AS runner ENV NODE_ENV=production +LABEL org.opencontainers.image.source="https://github.com/tekdi/ubi-strapi-provider-mw" \ + org.opencontainers.image.title="ubi-strapi-provider-mw" \ + org.opencontainers.image.description="Strapi Provider MW" @@ EXPOSE 7000 +HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --retries=3 \ + CMD wget -qO- http://127.0.0.1:7000/health || exit 1 CMD ["node", "dist/main.js"]
21-24: Nit: avoid --chmod=755 on JS/prisma sources.755 on source files is unnecessary; default read-only perms are fine.
Apply:
-COPY --chown=root:appgroup --chmod=755 prisma/ ./prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/dist/ ./dist/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/.prisma/ ./node_modules/.prisma/ -COPY --from=builder --chown=root:appgroup --chmod=755 /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/ +COPY --chown=root:appgroup prisma/ ./prisma/ +COPY --from=builder --chown=root:appgroup /app/dist/ ./dist/ +COPY --from=builder --chown=root:appgroup /app/node_modules/.prisma/ ./node_modules/.prisma/ +COPY --from=builder --chown=root:appgroup /app/node_modules/@prisma/client/ ./node_modules/@prisma/client/
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
Dockerfile(1 hunks)
🔇 Additional comments (1)
Dockerfile (1)
28-29: No changes needed: port binding matches EXPOSE 7000
The application already binds to 0.0.0.0 on port 7000 by default (app.listen(port, '0.0.0.0')with fallback to 7000), matching the Dockerfile’s EXPOSE and CMD.
|



PR Type
Enhancement
Description
Docker security hardening with non-root user
Added comprehensive dockerignore file
Updated service message string
Diagram Walkthrough
File Walkthrough
Dockerfile
Docker security hardening with non-root userDockerfile
appuserwith specific UID/GID 1001--chownflags.dockerignore
Comprehensive dockerignore file creation.dockerignore
app.service.ts
Updated service greeting messagesrc/app.service.ts
Backend!!'