|
1 | | -# - Stage 1 -------------------------------------------------------------------- |
| 1 | +# - Stage 1: Build dependencies into wheels ------------------------------------ |
2 | 2 |
|
3 | 3 | FROM python:3.12-slim-bookworm AS build |
4 | 4 |
|
5 | 5 | WORKDIR /app |
6 | 6 |
|
7 | | - # Install build tools needed to compile some Python packages |
| 7 | + # Install system build tools needed to compile Python packages with native |
| 8 | + # extensions |
8 | 9 | RUN apt-get update && apt-get install -y --no-install-recommends \ |
9 | 10 | build-essential gcc && \ |
10 | 11 | rm -rf /var/lib/apt/lists/* |
11 | 12 |
|
12 | | - # Copy and build all required packages (with dependencies) into wheels |
| 13 | + # Pre-build all third-party dependencies into wheel files. This enables faster, |
| 14 | + # more reliable installation later without relying on network access |
13 | 15 | COPY requirements.txt . |
14 | | - RUN pip wheel --no-cache -r requirements.txt -w /app/wheelhouse |
| 16 | + RUN pip wheel --no-cache-dir --wheel-dir=/app/wheelhouse -r requirements.txt |
15 | 17 |
|
16 | | - # Copy full app source (not strictly needed in build stage unless building static assets) |
17 | | - COPY . . |
18 | | - |
19 | | -# - Stage 2 -------------------------------------------------------------------- |
| 18 | + # - Stage 2: Runtime image ---------------------------------------------------- |
20 | 19 |
|
21 | 20 | FROM python:3.12-slim-bookworm AS runtime |
22 | 21 |
|
23 | 22 | WORKDIR /app |
24 | 23 |
|
25 | | - # Only bring in requirements and prebuilt wheels from build stage |
| 24 | + # Install dependencies from prebuilt wheels (no network access) |
| 25 | + # This improves build speed and avoids dependency drift |
26 | 26 | COPY requirements.txt . |
27 | 27 | COPY --from=build /app/wheelhouse /app/wheelhouse |
28 | | - |
29 | | - # Install app dependencies from local wheelhouse |
30 | 28 | RUN pip install --no-cache-dir --no-index --find-links /app/wheelhouse -r requirements.txt |
31 | 29 |
|
32 | | - # Copy only the necessary runtime source files |
| 30 | + # Copy only runtime-relevant application code (excluding tests and tooling) |
33 | 31 | COPY models ./models |
34 | 32 | COPY routes ./routes |
35 | 33 | COPY schemas ./schemas |
36 | 34 | COPY services ./services |
37 | 35 | COPY data ./data |
38 | 36 | COPY main.py . |
39 | 37 |
|
40 | | - # Add non-root user for security hardening |
| 38 | + # Copy README and assets needed for GHCR package page metadata |
| 39 | + COPY README.md ./ |
| 40 | + COPY assets ./assets |
| 41 | + |
| 42 | + # Add a non-root user for better container security |
41 | 43 | RUN adduser --disabled-password --gecos '' fastapi && \ |
42 | 44 | chown -R fastapi:fastapi /app |
43 | 45 | USER fastapi |
44 | 46 |
|
45 | | - # Prevent Python from buffering stdout/stderr |
| 47 | + # Ensure logs and errors appear in Docker logs immediately |
46 | 48 | ENV PYTHONUNBUFFERED=1 |
47 | 49 |
|
48 | | - # Expose FastAPI port |
| 50 | + # Expose FastAPI default port |
49 | 51 | EXPOSE 9000 |
50 | 52 |
|
51 | | - # Start the FastAPI app with Uvicorn |
| 53 | + # Start the FastAPI application using Uvicorn ASGI server |
52 | 54 | CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "9000"] |
0 commit comments