-
Notifications
You must be signed in to change notification settings - Fork 18
feat: add multi-stage Dockerfile for building and running app #342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughTwo new configuration files are introduced: a multi-stage Dockerfile for containerizing a FastAPI application with Python 3.12, and a commitlint configuration file to enforce commit message standards. The Dockerfile defines both build and runtime stages, installs dependencies, copies application files, sets up a non-root user, and configures the container to run the FastAPI app using uvicorn on port 9000. The commitlint configuration extends conventional rules, enforces line length limits, and excludes Dependabot-generated commits from linting. Changes
Sequence Diagram(s)sequenceDiagram
participant Developer
participant Docker Build (Build Stage)
participant Docker Build (Runtime Stage)
participant FastAPI App
Developer->>Docker Build (Build Stage): Build image (install dependencies, copy source)
Docker Build (Build Stage)->>Docker Build (Runtime Stage): Copy selected app files and dependencies
Docker Build (Runtime Stage)->>FastAPI App: Start container as non-root user
FastAPI App->>FastAPI App: Run uvicorn on port 9000
✨ Finishing Touches
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:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #342 +/- ##
=======================================
Coverage 89.18% 89.18%
=======================================
Files 2 2
Lines 111 111
=======================================
Hits 99 99
Misses 12 12
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
Dockerfile (2)
19-24: Selective app-copy is good—add a.dockerignore
You’re only copying needed subdirectories, which is great. To further slim your context, ensure you have a.dockerignore(e.g., exclude.git, tests, virtual environments, logs).
31-34: Add a HEALTHCHECK instruction
Consider a container-level healthcheck to detect if the app is responsive. For example, ping a/healthor/endpoint every 30s.EXPOSE 9000 ENV PYTHONUNBUFFERED=1 +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s \ + CMD curl -f http://0.0.0.0:9000/health || exit 1 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "9000"]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
Dockerfile(1 hunks)commitlint.config.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
commitlint.config.mjs (1)
Learnt from: nanotaboada
PR: nanotaboada/python-samples-fastapi-restful#331
File: .github/workflows/python-app.yml:22-24
Timestamp: 2025-04-17T19:22:41.270Z
Learning: The wagoid/commitlint-github-action GitHub Action uses @commitlint/config-conventional settings as a default fallback if no commitlint configuration file exists in the repository. This enforces Conventional Commits format with specific allowed types (build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test) and formatting rules.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (3)
commitlint.config.mjs (2)
2-2: Extend the conventional commitlint config correctly
Importing@commitlint/config-conventionallets you build on the default Conventional Commits rules.
4-9: Define custom header and body length rules
The overrides forheader-max-lengthandbody-max-line-lengthare applied correctly and will enforce an 80‑character limit.Dockerfile (1)
26-29: Non-root user setup is solid
Creating and switching to thefastapiuser hardens the container. Ownership change is correct.
| # Stage 2: Runtime | ||
| FROM python:3.12-slim-bookworm AS runtime | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY requirements.txt . | ||
| RUN pip install --no-cache-dir -r requirements.txt | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid duplicating pip install across stages
Both stages install from requirements.txt. Leverage the build stage to prepare wheels, then install from that wheelhouse in runtime to speed up builds and reduce image size.
# In the build stage:
-COPY requirements.txt .
-RUN pip install --no-cache-dir -r requirements.txt
+COPY requirements.txt .
+RUN pip wheel --no-cache --no-deps -r requirements.txt -w /app/wheelhouse
# In the runtime stage:
-COPY requirements.txt .
-RUN pip install --no-cache-dir -r requirements.txt
+COPY requirements.txt .
+COPY --from=build /app/wheelhouse /app/wheelhouse
+RUN pip install --no-cache-dir --no-index --find-links /app/wheelhouse -r requirements.txtCommittable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open a follow-up GitHub issue for this discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@nanotaboada I've created a follow-up GitHub issue to track the Dockerfile optimization we discussed. The issue includes the detailed explanation of how to avoid duplicating pip install across build stages by using wheels to speed up builds and reduce image size.
The issue has been assigned to you for future implementation when you're ready to address it.
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the Dockerfile optimization suggestion
gh issue create \
--title "Optimize Dockerfile: Avoid duplicating pip install across stages" \
--body "## Background
In PR #342, a multi-stage Dockerfile was introduced for the FastAPI application. The current implementation duplicates the \`pip install\` step in both the build and runtime stages.
## Suggested Improvement
Leverage the build stage to prepare wheels, then install from that wheelhouse in the runtime stage to speed up builds and reduce image size.
### Proposed Changes
\`\`\`diff
# In the build stage:
-COPY requirements.txt .
-RUN pip install --no-cache-dir -r requirements.txt
+COPY requirements.txt .
+RUN pip wheel --no-cache --no-deps -r requirements.txt -w /app/wheelhouse
# In the runtime stage:
-COPY requirements.txt .
-RUN pip install --no-cache-dir -r requirements.txt
+COPY requirements.txt .
+COPY --from=build /app/wheelhouse /app/wheelhouse
+RUN pip install --no-cache-dir --no-index --find-links /app/wheelhouse -r requirements.txt
\`\`\`
## Benefits
- Faster build times
- Reduced image size
- Better caching in CI/CD pipelines
## References
- PR: https://github.com/nanotaboada/python-samples-fastapi-restful/pull/342
- Discussion: https://github.com/nanotaboada/python-samples-fastapi-restful/pull/342#discussion_r2055005387
" \
--assignee "nanotaboada"
# Check if the issue was created successfully
if [ $? -eq 0 ]; then
echo "Issue created successfully."
else
echo "Failed to create issue. Error code: $?"
fi
Length of output: 1439
@nanotaboada Great! The issue has been successfully created as #345. You can access it directly at: #345
The issue includes all the details about optimizing the Dockerfile by avoiding duplication of the pip install step across stages, along with the code examples and benefits.
🐰✨
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

This change is
Summary by CodeRabbit