Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
83 changes: 41 additions & 42 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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 && \

Check warning on line 7 in Dockerfile

View check run for this annotation

Codeac.io / Codeac Code Quality

DL3008

Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
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"]
Loading