File size: 2,093 Bytes
4d1a589
a4508e8
 
 
 
 
 
 
 
 
 
4d1a589
a4508e8
4d1a589
3c35b12
 
 
a4508e8
 
 
 
 
 
 
 
 
 
a0473e2
a4508e8
 
 
 
 
 
 
 
 
a0473e2
a4508e8
 
 
a0473e2
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
# GPU Perf Prophet — CPU-only HF Spaces image (2 vCPU/16 GB free tier); build context is project root (data/models/, data/gpu_specs.yaml, data/pricing.yaml, src/, app/).

FROM python:3.11-slim

WORKDIR /app

# Install system deps required by some Python packages
RUN apt-get update && apt-get install -y --no-install-recommends \
        libgomp1 \
    && rm -rf /var/lib/apt/lists/*

# Install Python deps first (layer cached unless requirements.txt changes); requirements.txt is production-only (dev-only pytest/pytest-cov/httpx live in requirements-dev.txt, never installed here).
COPY requirements.txt .
# xgboost's Linux wheel unconditionally pulls in nvidia-nccl-cu12 (~300 MB, CUDA-only, unneeded for this CPU-only tree_method="hist" image); pre-install xgboost --no-deps (version read from requirements.txt) so pip's second pass treats it as satisfied and skips resolving/downloading nvidia-nccl-cu12, with the trailing uninstall kept as an unverified-on-real-Linux safety net so the shipped image can't contain it either way.
RUN pip install --no-cache-dir --no-deps "$(grep '^xgboost==' requirements.txt)" \
    && pip install --no-cache-dir -r requirements.txt \
    && pip uninstall -y nvidia-nccl-cu12

# Create a non-root user; HF Spaces also runs as UID 1000 by convention.
RUN useradd -m -u 1000 appuser

# Copy source and data artifacts
COPY src/       src/
COPY app/       app/
COPY data/gpu_specs.yaml  data/gpu_specs.yaml
COPY data/pricing.yaml    data/pricing.yaml
COPY data/models/         data/models/
COPY docker/supervisord.conf supervisord.conf

# Transfer ownership before dropping privileges.
RUN chown -R appuser /app

USER appuser

# HF Spaces expects the app to listen on port 7860
ENV PORT=7860

# Streamlit (7860, HF Spaces' externally-routed port) and FastAPI (8000, internal — Streamlit's only client, see app/api_client.py) both run in this container under supervisord (docker/supervisord.conf), which restarts either process if it dies — a bare shell `&` job can't do that.
EXPOSE 7860
EXPOSE 8000

CMD ["supervisord", "-c", "/app/supervisord.conf"]