Single sync worker means a slow request to / (compute_leaderboard, ~17s on dev / longer on h4a's compact CPU slice) blocks every other request, including the /healthz probe. With 2 worker processes and 4 threads each, slow requests on / no longer wedge the gunicorn queue, and /healthz responds promptly even while a /api/calculate is in flight.
30 lines
884 B
Docker
30 lines
884 B
Docker
FROM python:3.12-slim
|
|
|
|
ENV PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
PYTHONPATH=/app/src
|
|
|
|
WORKDIR /app
|
|
|
|
# Install dependencies only (not the package itself), so the source tree at
|
|
# /app stays the runtime layout the app expects: web.py uses
|
|
# Path(__file__).resolve().parents[2] / "data" / "raw" to find CSVs, which
|
|
# only resolves correctly when the package is imported from /app/src.
|
|
COPY pyproject.toml uv.lock ./
|
|
RUN pip install --no-cache-dir uv \
|
|
&& uv pip install --system --no-cache \
|
|
"pandas>=2.2" "scipy>=1.13" "numpy>=2.0" "flask>=3.0" "gunicorn>=21.0"
|
|
|
|
COPY src ./src
|
|
COPY data ./data
|
|
|
|
EXPOSE 8080
|
|
|
|
CMD ["gunicorn", "pluginbattery.web:app", \
|
|
"--bind", "0.0.0.0:8080", \
|
|
"--workers", "2", \
|
|
"--threads", "4", \
|
|
"--worker-class", "gthread", \
|
|
"--timeout", "120"]
|