File size: 1,974 Bytes
df5a768
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# ─────────────────────────────────────────────────────────────
#  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