Skip to content

Avoid duplicate backend image builds in Docker Compose#2934

Merged
arkid15r merged 4 commits intoOWASP:mainfrom
anurag2787:fix-docker-duplicate-image
Dec 16, 2025
Merged

Avoid duplicate backend image builds in Docker Compose#2934
arkid15r merged 4 commits intoOWASP:mainfrom
anurag2787:fix-docker-duplicate-image

Conversation

@anurag2787
Copy link
Contributor

Resolves #2927

Proposed change

Build the backend image once and used the same image for the worker as both services use the same code so building it twice is unnecessary.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

Summary by CodeRabbit

  • Chores
    • Strengthened service orchestration across production, staging, and local by ensuring backend services are fully started before worker services begin
    • Switched local development from build-from-source to using prebuilt container images to reduce setup time
    • Updated Redis connection defaults for the local worker environment to align with the new configuration

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

Walkthrough

Compose files updated to reuse a prebuilt backend image for worker services (instead of building twice), add startup ordering so workers wait for backend service_started, and adjust the local worker Redis host environment default.

Changes

Cohort / File(s) Summary
Local compose changes
docker-compose/local.yaml
Backend: added image: nest-local-backend alongside existing build. Worker: replaced build with image: nest-local-backend, added depends_on: backend: condition: service_started. Updated worker Redis host env default from nest-cache to cache (DJANGO_REDIS_HOST), kept Redis password default.
Production compose change
docker-compose/production.yaml
production-nest-worker: added depends_on: production-nest-backend: condition: service_started (worker now waits for backend to reach service_started).
Staging compose change
docker-compose/staging.yaml
staging-nest-worker: added depends_on: staging-nest-backend: condition: service_started (worker now waits for backend to reach service_started).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Check image name consistency between backend and worker in docker-compose/local.yaml.
  • Verify depends_on with service_started is supported and healthcheck/started condition configured for backend in each environment.
  • Confirm the local worker Redis env change (DJANGO_REDIS_HOST -> cache) matches service names and does not break connections.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: avoiding duplicate backend image builds in Docker Compose, which is the core objective of this PR.
Description check ✅ Passed The description is related to the changeset, explaining the proposed solution to build the backend image once and reuse it for the worker service.
Linked Issues check ✅ Passed The PR successfully addresses all objectives from issue #2927: it prevents duplicate builds by using a single built backend image for the worker service across all three environments (local, production, staging).
Out of Scope Changes check ✅ Passed All changes are within scope: modifications to docker-compose files for local, production, and staging environments to implement image reuse and add necessary service dependencies.
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

📜 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 70579bd and 26f1166.

📒 Files selected for processing (1)
  • docker-compose/local.yaml (2 hunks)
⏰ 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 unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (python)
🔇 Additional comments (2)
docker-compose/local.yaml (2)

9-9: LGTM: Backend image naming enables reuse.

Adding the image name alongside the build configuration correctly implements the image reuse pattern. Docker Compose will build and tag this image, allowing the worker service to reference it.


117-124: LGTM: Worker correctly reuses backend image.

The worker service now references the prebuilt backend image and includes a dependency on the backend service. This ensures the backend image is built before the worker attempts to use it, successfully avoiding duplicate builds as intended.


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.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docker-compose/local.yaml (2)

25-26: Critical: Fix the Redis password configuration bug in the backend service.

Line 26 uses ${DJANGO_REDIS_HOST:-nest-cache-password} to set DJANGO_REDIS_PASSWORD, which is incorrect—it should reference the DJANGO_REDIS_PASSWORD environment variable, not DJANGO_REDIS_HOST. This bug causes the Redis password to be misconfigured.

The worker service correctly fixes this at line 133, but the backend service still has the bug.

Apply this diff to fix the Redis password configuration:

     DJANGO_REDIS_HOST: ${DJANGO_REDIS_HOST:-nest-cache}
-    DJANGO_REDIS_PASSWORD: ${DJANGO_REDIS_HOST:-nest-cache-password}
+    DJANGO_REDIS_PASSWORD: ${DJANGO_REDIS_PASSWORD:-nest-cache-password}

25-25: Inconsistent Redis host defaults between backend and worker.

The backend service defaults DJANGO_REDIS_HOST to nest-cache (line 25), but the worker service defaults it to cache (line 132). Since the Redis service in local.yaml is named cache (line 35), the worker's default is correct and the backend's is wrong.

Both services should use the same default to avoid configuration inconsistencies.

Apply this diff to align the backend's Redis host default:

-    DJANGO_REDIS_HOST: ${DJANGO_REDIS_HOST:-nest-cache}
+    DJANGO_REDIS_HOST: ${DJANGO_REDIS_HOST:-cache}
     DJANGO_REDIS_PASSWORD: ${DJANGO_REDIS_PASSWORD:-nest-cache-password}

Also applies to: 132-132

♻️ Duplicate comments (1)
docker-compose/staging.yaml (1)

70-71: Same concern as production: clarify the startup dependency rationale.

Like production, the staging environment already shares the same prebuilt image (owasp/nest:backend-staging) between services—no duplicate builds occur. The added startup dependency raises the same questions about necessity and implementation as noted in the production.yaml review.

🧹 Nitpick comments (1)
docker-compose/local.yaml (1)

119-120: The startup dependency doesn't guarantee image build completion.

While using service_started ensures the backend container starts before the worker, it doesn't explicitly guarantee the image build has completed. In practice, Docker Compose builds all images before starting services, so this should work. However, the dependency seems unnecessary—the worker doesn't need the backend service to be running; it only needs the shared image to exist, which Docker Compose handles automatically.

Consider removing this dependency unless there's a specific runtime reason the worker needs the backend service to be started first.

📜 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 0165857 and 70579bd.

📒 Files selected for processing (3)
  • docker-compose/local.yaml (2 hunks)
  • docker-compose/production.yaml (1 hunks)
  • docker-compose/staging.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-17T10:40:27.924Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2211
File: backend/apps/nest/schedulers/calendar_events/base.py:27-31
Timestamp: 2025-09-17T10:40:27.924Z
Learning: In the OWASP/Nest project, the user ahmedxgouda has confirmed that enqueuing bound model methods (like self.reminder_schedule.reminder.delete) works in their RQ setup in backend/apps/nest/schedulers/calendar_events/base.py, despite potential serialization concerns.

Applied to files:

  • docker-compose/staging.yaml
  • docker-compose/production.yaml
🔇 Additional comments (4)
docker-compose/local.yaml (3)

9-12: LGTM! Backend image tagging enables reuse.

Adding the image directive alongside build correctly tags the built image as owasp/nest:backend-local, which allows the worker service to reference and reuse this same image instead of building separately.


117-117: LGTM! Worker now reuses the backend image.

Replacing the build directive with the image reference achieves the PR objective of preventing duplicate builds—the worker will use the same image built for the backend service.


133-133: LGTM! Redis password configuration bug fixed in worker.

The worker service now correctly references ${DJANGO_REDIS_PASSWORD:-nest-cache-password} instead of the erroneous ${DJANGO_REDIS_HOST:-nest-cache-password}. However, the same bug still exists in the backend service at line 26.

docker-compose/production.yaml (1)

71-72: The depends_on constraint for backend lacks clear justification and appears unnecessary.

The worker service runs independently: it uses python manage.py rqworker ai --with-scheduler to process background jobs from the RQ queue. Both the worker and backend share the same image and connect independently to the cache and database with their own health checks.

No runtime dependency exists—the worker doesn't make HTTP calls to the backend service, and there's no shared initialization logic requiring the backend to start first. If a legitimate startup ordering dependency exists, it should be documented; otherwise, removing this constraint would allow the services to start in parallel and improve startup performance. If a dependency is necessary, using service_healthy instead of service_started would be more appropriate.

⛔ Skipped due to learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2211
File: docker-compose/production.yaml:21-0
Timestamp: 2025-09-10T16:04:28.502Z
Learning: The RQ worker service (backend-worker) in production requires access to various secrets including the GitHub PEM file for potential GitHub API operations, even though primary tasks like Slack messaging use different credentials (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET). The worker might handle diverse background tasks beyond calendar/Slack operations that could require GitHub authentication.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
@anurag2787 anurag2787 marked this pull request as ready for review December 16, 2025 09:20
@sonarqubecloud
Copy link

Copy link
Collaborator

@ahmedxgouda ahmedxgouda left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@arkid15r arkid15r left a comment

Choose a reason for hiding this comment

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

Looks good, let's try this 👍

@arkid15r arkid15r added this pull request to the merge queue Dec 16, 2025
Merged via the queue into OWASP:main with commit 9a8d357 Dec 16, 2025
26 checks passed
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.

Update docker compose to build the backend image only once

3 participants