From 046de8a45f8b45b4506f4ae26979dc741f1a7f4b Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Mon, 12 May 2025 14:46:25 -0300 Subject: [PATCH 1/2] chore(containers): comply with SonarQube docker:S6504 --- Dockerfile | 83 +++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2c602c2..c1ed918 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,56 +1,55 @@ -# - Stage 1: Build dependencies into wheels ------------------------------------ +# - Stage 1: Builder ----------------------------------------------------------- - FROM python:3.13.3-slim-bookworm AS build +FROM python:3.13.3-slim-bookworm AS builder +WORKDIR /app - WORKDIR /app +# Install system build tools for packages with native extensions +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential gcc libffi-dev libssl-dev && \ + rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*.deb - # Install system build tools needed to compile Python packages with native - # extensions, and clean up afterward to reduce image size. - RUN apt-get update && \ - apt-get install -y --no-install-recommends build-essential gcc libffi-dev libssl-dev && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /var/cache/apt/archives/*.deb +# Pre-build all dependencies into wheels for reproducibility and speed +COPY --chown=root:root --chmod=644 requirements.txt . +RUN pip wheel --no-cache-dir --wheel-dir=/app/wheelhouse -r requirements.txt - # Pre-build all third-party dependencies into wheel files. This enables faster, - # more reliable installation later without relying on network access. - COPY requirements.txt . - RUN pip wheel --no-cache-dir --wheel-dir=/app/wheelhouse -r requirements.txt +# - Stage 2: Runtime ----------------------------------------------------------- -# - Stage 2: Runtime image ---------------------------------------------------- +FROM python:3.13.3-slim-bookworm AS runtime +WORKDIR /app - FROM python:3.13.3-slim-bookworm AS runtime +# Metadata labels +LABEL org.opencontainers.image.title="🧪 RESTful API with Python 3 and FastAPI" +LABEL org.opencontainers.image.description="Proof of Concept for a RESTful API made with Python 3 and FastAPI" +LABEL org.opencontainers.image.licenses="MIT" +LABEL org.opencontainers.image.source="https://github.com/nanotaboada/python-samples-fastapi-restful" - WORKDIR /app +# Copy prebuilt wheels and install dependencies +COPY --from=builder --chown=root:root --chmod=755 /app/wheelhouse /app/wheelhouse +COPY --chown=root:root --chmod=644 requirements.txt . +RUN pip install --no-cache-dir --no-index --find-links /app/wheelhouse -r requirements.txt && \ + rm -rf /app/wheelhouse - # Install runtime dependencies from prebuilt wheels (no network access). - # This improves build speed and avoids dependency drift. - 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 && \ - rm -rf /app/wheelhouse +# Copy application code (read-only) +COPY --chown=root:root --chmod=644 main.py ./ +COPY --chown=root:root --chmod=755 models ./models +COPY --chown=root:root --chmod=755 routes ./routes +COPY --chown=root:root --chmod=755 schemas ./schemas +COPY --chown=root:root --chmod=755 services ./services +COPY --chown=root:root --chmod=755 data ./data - # Copy only runtime-relevant application code (excluding tests and tooling) - COPY models ./models - COPY routes ./routes - COPY schemas ./schemas - COPY services ./services - COPY data ./data - COPY main.py . +# Copy metadata for GHCR (read-only) +COPY --chown=root:root --chmod=644 README.md ./ +COPY --chown=root:root --chmod=755 assets ./assets - # Copy README and assets needed for GHCR package page metadata - COPY README.md ./ - COPY assets ./assets +# Create a non-root user for running the app +RUN adduser --system --disabled-password --gecos '' fastapi - # Add a non-root user for better container security - RUN adduser --disabled-password --gecos '' fastapi && \ - chown -R fastapi:fastapi /app - USER fastapi +# Drop privileges +USER fastapi - # Ensure logs and errors appear in Docker logs immediately - ENV PYTHONUNBUFFERED=1 +# Logging output immediately +ENV PYTHONUNBUFFERED=1 - # Expose FastAPI default port - EXPOSE 9000 +EXPOSE 9000 - # Start the FastAPI application using Uvicorn ASGI server - CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "9000"] +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "9000"] From caf556ce1e27874731ff9e21a9fc58da8642ae63 Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Mon, 12 May 2025 14:47:47 -0300 Subject: [PATCH 2/2] chore: add VS Code extension recommendations --- .vscode/extensions.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..b657926 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,14 @@ +{ + "recommendations": [ + "ms-python.python", + "ms-python.vscode-pylance", + "github.vscode-pull-request-github", + "github.vscode-github-actions", + "ms-azuretools.vscode-containers", + "redhat.vscode-yaml", + "sonarsource.sonarlint-vscode", + "esbenp.prettier-vscode", + "conventionalcommits.extension", + "codezombiech.gitignore" + ] +}