Skip to content

Conversation

@arkid15r
Copy link
Collaborator

Proposed change

Refactor docker files.

Checklist

  • Required: I read and followed the contributing guidelines
  • Required: I ran make check-test locally and all tests passed
  • I used AI for code, documentation, or tests in this PR

@github-actions github-actions bot added backend frontend docker Pull requests that update Docker code makefile ci labels Dec 31, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Summary by CodeRabbit

  • Chores

    • Consolidated Docker layout and reorganized build artifacts for backend, frontend and tooling.
    • Updated CI/CD workflows and local compose to use the new layout and unified gha-based caching.
    • Simplified local build flags by removing the Compose Bake toggle while keeping BuildKit enabled.
  • Tests

    • Adjusted test orchestration to run containerized unit and e2e tests with expanded project mounts and improved env handling.
  • New Features

    • Added a containerized spell-check tool.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Consolidates Docker assets under a unified /docker directory, repoints CI and Dependabot to the new paths, updates Makefiles and docker-compose to use root build contexts, adds a cspell Dockerfile, and expands test/run steps to use explicit env-files and read-only volume mounts. (34 words)

Changes

Cohort / File(s) Summary
Repo config & CI
/.github/dependabot.yml, /.github/workflows/run-ci-cd.yaml, /.github/workflows/update-nest-test-images.yaml
Repointed Dependabot targets and CI Docker build steps to docker/* Dockerfiles with root build context; unified GHA cache config; renamed some steps and adjusted image tags and run/mounts.
Top-level Makefile
/Makefile
Removed COMPOSE_BAKE from run target; retained DOCKER_BUILDKIT=1 for compose invocation.
Service Makefiles
backend/Makefile, frontend/Makefile
Updated docker build -f paths to docker/... with . context; expanded docker run to use --env-file, -e NEXT_PUBLIC_ENVIRONMENT=local, and multiple read-only volume mounts; removed a build-time NEXT_PUBLIC_ENVIRONMENT arg for some frontend test builds.
Docker Compose (local)
docker-compose/local/compose.yaml
Changed build.context to repo root and Dockerfile paths to docker/backend/Dockerfile.local, docker/docs/Dockerfile.local, docker/frontend/Dockerfile.local.
Backend Dockerfiles
docker/backend/Dockerfile, docker/backend/Dockerfile.local, docker/backend/Dockerfile.test
Adjusted COPY sources to use backend/ subpaths for poetry and app files; updated entrypoint source; test Dockerfile narrows copied files to backend-specific layout.
Frontend Dockerfiles
docker/frontend/Dockerfile.local, docker/frontend/Dockerfile.unit.test, docker/frontend/Dockerfile.e2e.test
Moved package files to frontend/ paths; unit-test Dockerfile removes copying many source/test files and drops USER node; added new multi-stage e2e test Dockerfile (docker/frontend/Dockerfile.e2e.test).
New tooling Dockerfile
docker/cspell/Dockerfile
Added Node (Alpine) Dockerfile for cspell using pnpm, cache mounts, and entrypoint set to the cspell binary.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • kasya

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: refactoring Docker files and test images, which aligns with the extensive changes across Docker-related configurations.
Description check ✅ Passed The description directly relates to the changeset, stating 'Refactor docker files' which matches the PR's focus on Docker reorganization and consolidation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ark/refactor-docker

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e728fa8 and a9a807c.

📒 Files selected for processing (1)
  • .github/workflows/run-ci-cd.yaml
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-26T06:08:58.549Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:08:58.549Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (5)
.github/workflows/run-ci-cd.yaml (5)

161-164: LGTM! Improved caching and consistent path structure.

The changes correctly use root context (.) with the new centralized Dockerfile path (docker/backend/Dockerfile.test). The mode=max cache configuration will maximize cache layer storage for faster subsequent builds.


169-180: LGTM! Enhanced security with readonly mounts.

The refactored test run uses readonly bind mounts for each required directory, which follows the principle of least privilege and prevents accidental modifications to the source code during test execution. Using --env-file also improves maintainability.


196-220: LGTM! Consistent test pattern with security improvements.

Both the build and run steps follow the same improved patterns as the backend tests: root context for builds, maximized caching, and readonly mounts for test runs. The step name change improves consistency.


236-262: LGTM! E2E tests follow consistent secure pattern.

The e2e test configuration appropriately mounts additional configuration files needed for end-to-end testing while maintaining readonly access and using the centralized Docker build structure.


321-322: LGTM! Staging backend build uses correct context.

The staging backend build correctly uses root context (.) with the centralized Dockerfile path, consistent with the refactoring pattern.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@arkid15r arkid15r changed the title Ark/refactor docker Refactor docker files / test images Dec 31, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c29a4db and 4af6ed1.

📒 Files selected for processing (17)
  • .github/dependabot.yml
  • .github/workflows/run-ci-cd.yaml
  • .github/workflows/update-nest-test-images.yaml
  • Makefile
  • backend/Makefile
  • backend/entrypoint.sh
  • docker-compose/local/compose.yaml
  • docker/backend/Dockerfile
  • docker/backend/Dockerfile.local
  • docker/backend/Dockerfile.test
  • docker/cspell/Dockerfile
  • docker/docs/Dockerfile.local
  • docker/frontend/Dockerfile
  • docker/frontend/Dockerfile.e2e.test
  • docker/frontend/Dockerfile.local
  • docker/frontend/Dockerfile.unit.test
  • frontend/Makefile
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.

Applied to files:

  • frontend/Makefile
  • backend/Makefile
📚 Learning: 2025-12-26T06:08:58.549Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:08:58.549Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
  • .github/workflows/update-nest-test-images.yaml
  • backend/Makefile
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
  • .github/workflows/update-nest-test-images.yaml
📚 Learning: 2025-12-26T06:08:58.549Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:08:58.549Z
Learning: Ensure Redis image versions stay in sync across all environments by updating every relevant YAML file together (docker-compose files and CI/CD workflow configurations). When upgrading Redis, bump the image version in all docker-compose files and in all CI workflow YAMLs in one coordinated change to maintain parity across production, staging, local, E2E, and CI tests.

Applied to files:

  • docker-compose/local/compose.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (21)
docker/cspell/Dockerfile (4)

3-12: LGTM! Good security and performance practices.

The environment setup correctly:

  • Uses cache mounts for faster builds
  • Configures retry logic for network resilience
  • Employs --ignore-scripts to prevent execution of potentially malicious scripts during installation

14-19: LGTM! Proper layer caching and dependency management.

The implementation follows Docker best practices by:

  • Copying dependency manifests before installation (optimizes layer caching)
  • Using --frozen-lockfile for reproducible builds
  • Leveraging cache mounts for the pnpm store
  • Separating installation context (/opt/node) from runtime context (/nest)

21-23: LGTM! Secure runtime configuration.

The entrypoint correctly references the installed cspell binary, and using the non-root node user follows security best practices for containerized applications.


1-1: No action required—node:24-alpine is a valid LTS release.

Node.js v24 is an officially supported LTS release (released October 2024) and follows the standard even-numbered LTS versioning scheme. The node:24-alpine image is a standard, stable offering on Docker Hub and is appropriate for production use.

Likely an incorrect or invalid review comment.

Makefile (1)

53-53: Verify that removing COMPOSE_BAKE doesn't affect functionality.

The COMPOSE_BAKE=true flag was removed, leaving only DOCKER_BUILDKIT=1. Confirm this change doesn't break any docker compose features or build optimizations that depended on the bake functionality.

docker/backend/Dockerfile.test (1)

27-27: COPY paths correctly reflect the repository root build context.

The updated paths with backend/ prefixes are consistent with the new build context structure where the context is at the repository root.

Also applies to: 31-31

docker/frontend/Dockerfile.e2e.test (1)

16-16: LGTM! Improved security with explicit permissions.

The updated COPY instruction correctly reflects the repository root build context and adds explicit read-only permissions (444) and root ownership, which is a security best practice for dependency manifests.

backend/Makefile (1)

120-133: Enhanced test workflow with improved volume mounting strategy.

The updated test target includes several improvements:

  • Dockerfile path aligns with the new Docker organization
  • Explicit DJANGO_SETTINGS_MODULE setting improves clarity
  • Multiple read-only volume mounts enable testing against live code without image rebuilds
  • The --rm flag ensures proper cleanup

Note that this changes the test strategy to mount host directories rather than copying them into the image. While this improves development workflow, verify that the test environment still matches production image behavior.

docker/backend/Dockerfile.local (1)

29-29: COPY paths correctly updated for the new build context.

The change aligns with the repository-wide Docker reorganization, using backend/ prefixed paths and explicit permissions consistent with other backend Dockerfiles.

docker/frontend/Dockerfile.local (1)

28-28: LGTM! Consistent with the Docker reorganization.

The updated COPY instruction correctly uses frontend/ prefixed paths and adds explicit read-only permissions and root ownership, matching the security improvements in other frontend Dockerfiles.

.github/dependabot.yml (1)

4-4: Directory paths confirmed to exist at new locations.

All four directories referenced in the dependabot.yml configuration have been verified to exist:

  • /docker/backend
  • /docker/cspell
  • /docker/docs
  • /docker/frontend

The paths correctly reflect the consolidated /docker directory structure, and the dependabot configuration is properly aligned with the reorganization.

docker/backend/Dockerfile (1)

39-39: No action required – the entrypoint.sh file exists at the expected location.

The file exists at backend/entrypoint.sh, which is the correct location for the COPY entrypoint.sh entrypoint.sh instruction when the build context is the repository root. This is consistent with other COPY instructions in the builder stage that reference files in the backend/ directory.

.github/workflows/update-nest-test-images.yaml (2)

40-41: LGTM! Build contexts and Dockerfile paths correctly updated.

All three test image builds now consistently use the repository root as context (.) with Dockerfile paths pointing to the new centralized docker/ directory structure. This aligns perfectly with the PR's refactoring goals.

Also applies to: 55-56, 70-71


61-61: Minor naming consistency improvement.

Renaming from "Update frontend end-to-end test image" to "Update frontend e2e test image" improves consistency with the step name on Line 244 of .github/workflows/run-ci-cd.yaml.

docker/frontend/Dockerfile.unit.test (1)

16-21: LGTM! Dockerfile correctly adapted for new build context.

The COPY paths now correctly reference frontend/package.json and frontend/pnpm-lock.yaml since the build context is the repository root. The minimal image (dependencies only, no source code) aligns with the runtime volume mount strategy seen in frontend/Makefile, where test files and source code are mounted at runtime. This approach improves development workflow by avoiding rebuilds when source code changes.

docker-compose/local/compose.yaml (1)

11-12: LGTM! Docker Compose service definitions correctly updated.

All service build configurations now consistently use the repository root as context with Dockerfile paths pointing to the new docker/ directory structure:

  • Backend: docker/backend/Dockerfile.local
  • Docs: docker/docs/Dockerfile.local
  • Frontend: docker/frontend/Dockerfile.local

This centralization improves maintainability and aligns with the PR's refactoring objectives.

Also applies to: 79-79, 95-96

frontend/Makefile (2)

60-63: LGTM! Build commands correctly updated for new Docker structure.

Build commands now use repository root as context with Dockerfile paths pointing to docker/frontend/. The removal of --build-arg NEXT_PUBLIC_ENVIRONMENT=local from build time is appropriate since it's now set at runtime (Lines 67, 87), improving image reusability.

Also applies to: 80-83


64-77: Excellent runtime volume mount strategy.

The extensive use of read-only volume mounts for source code, tests, and configuration files is a significant improvement:

  • Eliminates need to rebuild images when source code changes
  • Speeds up development workflow
  • All mounts are read-only (:ro), following security best practices
  • Aligns with the lightweight Docker images approach

This pattern works well with the minimal test images that only contain dependencies.

Also applies to: 84-95

.github/workflows/run-ci-cd.yaml (3)

167-168: LGTM! Test image builds correctly updated.

All test image builds now consistently use repository root as context (.) with Dockerfile paths pointing to the centralized docker/ directory structure. This aligns with the refactoring goals.

Also applies to: 209-210, 253-254


175-184: Excellent improvement to test execution strategy.

The extensive use of bind mounts for source code, tests, and configuration files significantly improves the CI/CD workflow:

  • Changes to source code don't require image rebuilds
  • Faster iteration during development and debugging
  • All mounts are read-only, following security best practices
  • Aligns with the lightweight test image approach

Also applies to: 217-228, 261-274


333-334: LGTM! Staging backend build configuration correctly updated.

Both context and Dockerfile path have been updated to use the repository root and centralized docker/ directory structure.

Comment on lines 381 to +382
context: frontend
file: frontend/docker/Dockerfile
file: docker/frontend/Dockerfile
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Step 1: Explore repository structure for Dockerfiles
echo "=== Finding all Dockerfiles ==="
fd -t f "Dockerfile" --max-depth 5

echo -e "\n=== Checking if docker/ directory exists at repo root ==="
ls -la docker/ 2>/dev/null || echo "docker/ directory not found at repo root"

echo -e "\n=== Repository root structure ==="
ls -la | head -20

Repository: OWASP/Nest

Length of output: 2001


🏁 Script executed:

#!/bin/bash
# Step 2: Check the workflow file structure and extract the specific lines mentioned
echo "=== Checking workflow file size ==="
wc -l .github/workflows/run-ci-cd.yaml

echo -e "\n=== Lines 375-390 (staging frontend build) ==="
sed -n '375,390p' .github/workflows/run-ci-cd.yaml

echo -e "\n=== Lines 650-665 (production backend build) ==="
sed -n '650,665p' .github/workflows/run-ci-cd.yaml

echo -e "\n=== Lines 695-710 (production frontend build) ==="
sed -n '695,710p' .github/workflows/run-ci-cd.yaml

Repository: OWASP/Nest

Length of output: 1914


🏁 Script executed:

#!/bin/bash
# Step 3: Use yq to extract the exact context and file values for the three builds
if command -v yq &> /dev/null; then
  echo "=== Extracting build configurations using yq ==="
  echo "Staging frontend:"
  yq eval '.jobs.build-staging-images.steps[] | select(.name == "Build frontend image") | {context: .with.context, file: .with.file}' .github/workflows/run-ci-cd.yaml
  
  echo -e "\nProduction backend:"
  yq eval '.jobs.build-production-images.steps[] | select(.name == "Build backend image") | {context: .with.context, file: .with.file}' .github/workflows/run-ci-cd.yaml
  
  echo -e "\nProduction frontend:"
  yq eval '.jobs.build-production-images.steps[] | select(.name == "Build frontend image") | {context: .with.context, file: .with.file}' .github/workflows/run-ci-cd.yaml
else
  echo "yq not available, will extract manually"
fi

Repository: OWASP/Nest

Length of output: 93


🏁 Script executed:

#!/bin/bash
# Step 1: Search for all build-push-action steps to identify patterns
echo "=== All docker/build-push-action steps in workflow ==="
grep -n "name: Build" .github/workflows/run-ci-cd.yaml
echo ""
echo "=== Checking all context values in workflow ==="
grep -n "context:" .github/workflows/run-ci-cd.yaml
echo ""
echo "=== Checking all file values in workflow ==="
grep -n "file:" .github/workflows/run-ci-cd.yaml

Repository: OWASP/Nest

Length of output: 1115


🏁 Script executed:

#!/bin/bash
# Step 2: Check git history to understand when/if Dockerfiles were moved
echo "=== Recent commits mentioning docker or Dockerfile ==="
git log --oneline --all -20 -- docker/ | head -20

echo -e "\n=== Check if Dockerfiles exist at old locations (root level) ==="
ls -la | grep -i docker || echo "No Dockerfile at repo root"

echo -e "\n=== Check for backend/Dockerfile or frontend/Dockerfile at root ==="
if [ -f "backend/Dockerfile" ]; then
  echo "Found backend/Dockerfile at root"
else
  echo "backend/Dockerfile does NOT exist at root"
fi

if [ -f "frontend/Dockerfile" ]; then
  echo "Found frontend/Dockerfile at root"
else
  echo "frontend/Dockerfile does NOT exist at root"
fi

Repository: OWASP/Nest

Length of output: 554


🏁 Script executed:

#!/bin/bash
# Step 3: Verify if docker-compose or other files reference Dockerfiles to understand the pattern
echo "=== Checking docker-compose files ==="
find . -maxdepth 3 -name "docker-compose*" -type f | head -10

if [ -f "docker-compose.yml" ] || [ -f "docker-compose.yaml" ]; then
  echo ""
  echo "=== docker-compose context patterns ==="
  grep -A2 "build:" docker-compose.yml docker-compose.yaml 2>/dev/null | head -40
fi

Repository: OWASP/Nest

Length of output: 91


Critical: Inconsistent build context and Dockerfile paths will break builds.

Three build configurations have mismatched context and Dockerfile paths:

  1. Staging frontend (Lines 381-382):

    • Context: frontend
    • File: docker/frontend/Dockerfile
    • Result: Docker will look for frontend/docker/frontend/Dockerfile
  2. Production backend (Lines 658-659):

    • Context: backend
    • File: docker/backend/Dockerfile
    • Result: Docker will look for backend/docker/backend/Dockerfile
  3. Production frontend (Lines 704-705):

    • Context: frontend
    • File: docker/frontend/Dockerfile
    • Result: Docker will look for frontend/docker/frontend/Dockerfile

The Dockerfile paths are relative to the specified context directory. Since all Dockerfiles are located in the centralized docker/ directory at the repository root (not at backend/Dockerfile or frontend/Dockerfile), the context should be . (repository root) for all three builds. Note that other builds in this workflow (test images and staging backend) already use the correct pattern with context: ..

🔎 Proposed fix

For staging frontend build:

       - name: Build frontend image
         uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
         with:
           cache-from: |
             type=gha
             type=registry,ref=owasp/nest:frontend-staging-cache
           cache-to: |
             type=registry,ref=owasp/nest:frontend-staging-cache
-          context: frontend
+          context: .
           file: docker/frontend/Dockerfile

For production backend build:

       - name: Build backend image
         uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
         with:
           build-args: |
             OWASP_GID=1002
             OWASP_UID=1002
           cache-from: |
             type=gha
             type=registry,ref=owasp/nest:backend-staging-cache
-          context: backend
+          context: .
           file: docker/backend/Dockerfile

For production frontend build:

       - name: Build frontend image
         uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
         with:
           cache-from: |
             type=gha
             type=registry,ref=owasp/nest:frontend-staging-cache
-          context: frontend
+          context: .
           file: docker/frontend/Dockerfile
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
context: frontend
file: frontend/docker/Dockerfile
file: docker/frontend/Dockerfile
context: .
file: docker/frontend/Dockerfile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
docker/frontend/Dockerfile.e2e.test (1)

22-31: Consider reducing duplication between stages.

The environment variables (Lines 22-28) and pnpm installation (Lines 30-31) are duplicated from the builder stage. While not critical, you could refactor using a base image or ARGs to improve maintainability.

🔎 Example refactor using a common base
+FROM node:24-alpine AS base
+
+ENV FORCE_COLOR=1 \
+    NPM_CACHE="/app/.npm" \
+    PNPM_HOME="/pnpm"
+
+ENV NPM_CONFIG_RETRY=5 \
+    NPM_CONFIG_TIMEOUT=30000 \
+    PATH="$PNPM_HOME:$PATH"
+
+RUN --mount=type=cache,target=${NPM_CACHE} \
+    npm install --ignore-scripts -g pnpm --cache ${NPM_CACHE}
+
-FROM node:24-alpine AS builder
+FROM base AS builder
-
-ENV FORCE_COLOR=1 \
-    NPM_CACHE="/app/.npm" \
-    PNPM_HOME="/pnpm"
-
-ENV NPM_CONFIG_RETRY=5 \
-    NPM_CONFIG_TIMEOUT=30000 \
-    PATH="$PNPM_HOME:$PATH"
-
-RUN --mount=type=cache,target=${NPM_CACHE} \
-    npm install --ignore-scripts -g pnpm --cache ${NPM_CACHE}

 WORKDIR /app

 COPY --chmod=444 --chown=root:root frontend/package.json frontend/pnpm-lock.yaml ./
 RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
     pnpm install --frozen-lockfile --ignore-scripts

 FROM mcr.microsoft.com/playwright:v1.57.0-jammy

-ENV FORCE_COLOR=1 \
-    NPM_CACHE="/app/.npm" \
-    PNPM_HOME="/pnpm"
-
-ENV NPM_CONFIG_RETRY=5 \
-    NPM_CONFIG_TIMEOUT=30000 \
-    PATH="$PNPM_HOME:$PATH"
-
-RUN --mount=type=cache,target=${NPM_CACHE} \
-    npm install --ignore-scripts -g pnpm --cache ${NPM_CACHE}
+COPY --from=base /usr/local/lib/node_modules/pnpm /usr/local/lib/node_modules/pnpm
+COPY --from=base /usr/local/bin/pnpm /usr/local/bin/pnpm
+
+ENV PNPM_HOME="/pnpm" \
+    PATH="/pnpm:$PATH"

 WORKDIR /app

 COPY --from=builder --chown=root:root /app/node_modules ./node_modules
 COPY --from=builder --chown=root:root /app/package.json ./package.json

Note: This approach copies pnpm binaries from the base stage instead of reinstalling, but you may need to adjust paths if the Playwright base image has different system library requirements.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f375a95 and e728fa8.

📒 Files selected for processing (2)
  • .github/workflows/run-ci-cd.yaml
  • docker/frontend/Dockerfile.e2e.test
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-26T06:08:58.549Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:08:58.549Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (6)
docker/frontend/Dockerfile.e2e.test (2)

1-19: LGTM - Builder stage correctly optimized for caching.

The builder stage properly leverages cache mounts and sets secure file ownership. The COPY instruction on Line 16 correctly assumes a root build context (.), which aligns with the workflow changes that set context: ..


20-20: The Dockerfile is using Playwright v1.57.0, which is the latest stable release as of December 2025. No action required.

.github/workflows/run-ci-cd.yaml (4)

158-180: LGTM - Backend test build and execution correctly configured.

The backend test image build correctly uses context: . with docker/backend/Dockerfile.test, and the test execution properly mounts all required directories as read-only volumes. The use of GHA caching with zstd compression optimizes CI performance.


196-220: LGTM - Frontend unit test configuration is correct.

The unit test image build correctly uses context: . with docker/frontend/Dockerfile.unit.test, and the test execution mounts all necessary files and directories as read-only volumes. The configuration aligns well with the docker/ refactoring.


236-262: LGTM - Frontend e2e test configuration is comprehensive.

The e2e test image build correctly uses context: . with docker/frontend/Dockerfile.e2e.test, and the test execution mounts all necessary configuration files and directories as read-only volumes. The configuration properly supports Playwright e2e testing.


310-326: LGTM - Staging backend build correctly configured.

The staging backend build correctly uses context: . with docker/backend/Dockerfile, properly aligning with the centralized docker/ directory structure.

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend ci docker Pull requests that update Docker code frontend makefile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants