Skip to content

chore: optimize Dockerfile for quicker builds#4418

Open
cemreinanc wants to merge 2 commits intomainfrom
chore/optimize-dockerfile-copy
Open

chore: optimize Dockerfile for quicker builds#4418
cemreinanc wants to merge 2 commits intomainfrom
chore/optimize-dockerfile-copy

Conversation

@cemreinanc
Copy link
Contributor

@cemreinanc cemreinanc commented Feb 25, 2026

  • Added a new build stage for collecting Django static files in parallel with the frontend build. (10-20 seconds)
  • Updated file copying commands to set ownership for the application files. (Removes 60-90 seconds recursive chown step)

Summary by CodeRabbit

  • Chores
    • Optimized container build with parallel asset collection for faster builds.
    • Improved runtime security by running the container as a non-root user and enforcing consistent file ownership.
    • Streamlined static asset handling by pre-collecting assets during build, reducing startup work and ensuring consistent assets at runtime.

- Added a new build stage for collecting Django static files in parallel with the frontend build.
- Updated file copying commands to set ownership for the application files.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

📝 Walkthrough

Walkthrough

Restructures the Dockerfile to add a backend_static stage for parallel Django collectstatic, propagate pre-built static/frontend assets into the final image using --chown=1001:0, and switch to non-root USER 1001 earlier while removing in-final collectstatic steps.

Changes

Cohort / File(s) Summary
Dockerfile (multi-stage build)
Dockerfile
Added backend_static stage to run Django collectstatic in parallel with frontend build; final stage now copies pre-collected static and frontend assets instead of running collectstatic at build-time. All final-stage COPY instructions use --chown=1001:0. Non-root USER 1001 is set earlier and /app ownership is established earlier.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Dev as "Dev / CI"
    participant Frontend as "frontend build stage"
    participant BackendStatic as "backend_static (collectstatic)"
    participant Final as "final image stage"

    Dev->>Frontend: start frontend build (assets)
    Dev->>BackendStatic: run Django collectstatic (pre-collect static)
    Frontend-->>Final: copy built frontend assets (--chown=1001:0)
    BackendStatic-->>Final: copy collected static files (--chown=1001:0)
    Dev->>Final: copy source & deps with --chown=1001:0 and switch to USER 1001
    Note right of Final: Final image contains pre-built assets and non-root user
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Docker Builds Optimization #4162: Modifies Dockerfile multi-stage build strategy and asset/ownership transfer mechanisms between stages, directly related to parallelizing builds and changing collectstatic/asset propagation.

Suggested reviewers

  • elisescu

Poem

🐰 In layered stages I hop and hum,
Pre-built sprites and static come,
Chown in hand, I pass them on,
Non-root tunnels at early dawn,
A nimble build — a rabbit's drum. 🥕

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: optimize Dockerfile for quicker builds' directly aligns with the PR's main objective of optimizing the Dockerfile for faster builds by parallelizing static file collection and improving file ownership handling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/optimize-dockerfile-copy

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.

🧹 Nitpick comments (1)
Dockerfile (1)

58-58: Consider copying only the files needed for collectstatic to improve cache hit rates.

COPY . /app/ pulls in the entire build context (including frontend source, docs, etc.), so any file change — even a frontend-only change — busts the cache for this stage. Since the goal is only to run collectstatic, you could narrow the copy to Python/Django files. That said, since this stage runs in parallel with the frontend build, the wall-clock impact is minimal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` at line 58, The Dockerfile currently uses COPY . /app/ which
pulls the whole build context and busts cache for the collectstatic stage;
replace this with a minimal copy of only the files needed to run collectstatic
(e.g., COPY requirements.txt /app/ and install deps, then COPY manage.py, your
Django package folders (e.g., myapp/, settings/, urls/), templates/ and static/
into /app/) or add a .dockerignore to exclude frontend/, docs/, node_modules/;
update the Dockerfile stage that runs collectstatic (the step referencing COPY .
/app/) to use those targeted COPY lines so cache is preserved and collectstatic
runs with only Python/Django sources.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Dockerfile`:
- Line 58: The Dockerfile currently uses COPY . /app/ which pulls the whole
build context and busts cache for the collectstatic stage; replace this with a
minimal copy of only the files needed to run collectstatic (e.g., COPY
requirements.txt /app/ and install deps, then COPY manage.py, your Django
package folders (e.g., myapp/, settings/, urls/), templates/ and static/ into
/app/) or add a .dockerignore to exclude frontend/, docs/, node_modules/; update
the Dockerfile stage that runs collectstatic (the step referencing COPY . /app/)
to use those targeted COPY lines so cache is preserved and collectstatic runs
with only Python/Django sources.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8ac136 and 9a9551c.

📒 Files selected for processing (1)
  • Dockerfile

@github-actions
Copy link
Contributor

github-actions bot commented Feb 25, 2026

🚀 Preview Environment

Your preview environment is ready!

Resource Details
🌐 Preview URL https://metaculus-pr-4418-chore-optimize-dockerfile-copy-preview.mtcl.cc
📦 Docker Image ghcr.io/metaculus/metaculus:chore-optimize-dockerfile-copy-1c3edb9
🗄️ PostgreSQL NeonDB branch preview/pr-4418-chore-optimize-dockerfile-copy
Redis Fly Redis mtc-redis-pr-4418-chore-optimize-dockerfile-copy

Details

  • Commit: fb6bfb7b6b14fbbdd924310e181435ec81a22d11
  • Branch: chore/optimize-dockerfile-copy
  • Fly App: metaculus-pr-4418-chore-optimize-dockerfile-copy

ℹ️ Preview Environment Info

Isolation:

  • PostgreSQL and Redis are fully isolated from production
  • Each PR gets its own database branch and Redis instance
  • Changes pushed to this PR will trigger a new deployment

Limitations:

  • Background workers and cron jobs are not deployed in preview environments
  • If you need to test background jobs, use Heroku staging environments

Cleanup:

  • This preview will be automatically destroyed when the PR is closed

@cemreinanc cemreinanc marked this pull request as draft February 25, 2026 09:56
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.

🧹 Nitpick comments (1)
Dockerfile (1)

58-58: Consider scoping the COPY to backend-only files for more efficient layering.

While your .dockerignore properly excludes sensitive files like .env, the full COPY . /app/ still pulls unnecessary files (frontend assets, tests, documentation, etc.) into this intermediate stage where only the Django backend is needed for collectstatic. Scoping this copy reduces intermediate layer size and follows the pattern already used in the frontend_build stage (COPY front_end/ /app/front_end/).

♻️ Proposed scoped COPY
-COPY . /app/
+COPY manage.py pyproject.toml poetry.lock /app/
+COPY <your_django_app_dir>/ /app/<your_django_app_dir>/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` at line 58, Replace the broad "COPY . /app/" in the Dockerfile
with a scoped copy that only brings backend/Django sources and static assets
needed for collectstatic into the build stage (e.g., copy the backend app
directory, requirements, manage.py, templates, and static folders), mirroring
the pattern used in the frontend_build stage's "COPY front_end/
/app/front_end/"; update the stage that runs collectstatic to use those
backend-only paths so intermediate layers are smaller and frontend/tests/docs
are excluded from this stage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Dockerfile`:
- Line 58: Replace the broad "COPY . /app/" in the Dockerfile with a scoped copy
that only brings backend/Django sources and static assets needed for
collectstatic into the build stage (e.g., copy the backend app directory,
requirements, manage.py, templates, and static folders), mirroring the pattern
used in the frontend_build stage's "COPY front_end/ /app/front_end/"; update the
stage that runs collectstatic to use those backend-only paths so intermediate
layers are smaller and frontend/tests/docs are excluded from this stage.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a9551c and 1c3edb9.

📒 Files selected for processing (1)
  • Dockerfile

Copy link
Contributor

@hlbmtc hlbmtc left a comment

Choose a reason for hiding this comment

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

Nice

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.

2 participants