# ───────────────────────────────────────────────────────────── # Stage 1 — builder (install heavy deps, keeps final image lean) # ───────────────────────────────────────────────────────────── FROM python:3.11-slim AS builder WORKDIR /install # System deps needed for some wheels RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ g++ \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . # Install into a prefix so we can copy cleanly to final stage RUN pip install --prefix=/install/pkg --no-cache-dir -r requirements.txt # ───────────────────────────────────────────────────────────── # Stage 2 — runtime # ───────────────────────────────────────────────────────────── FROM python:3.11-slim # Non-root user for security RUN useradd -m -u 1000 appuser WORKDIR /app # Copy installed packages from builder COPY --from=builder /install/pkg /usr/local # Copy application files COPY app.py . COPY model_LSTM.pth . COPY scaler.joblib . COPY templates/ ./templates/ # Ownership RUN chown -R appuser:appuser /app USER appuser # Gunicorn settings via env (overrideable at runtime) ENV PORT=5000 \ WORKERS=2 \ TIMEOUT=120 \ FLASK_DEBUG=0 EXPOSE ${PORT} # Use gunicorn in production; falls back to Flask dev server if not found CMD gunicorn \ --bind "0.0.0.0:${PORT}" \ --workers ${WORKERS} \ --timeout ${TIMEOUT} \ --access-logfile - \ --error-logfile - \ app:app