# Self-contained demo-tier image for Hugging Face Spaces (Docker SDK). # Lives at the repo root because HF builds `docker build .` from here. # The baked index is built INTO the image, so the demo is never empty after a # host restart. Runs FastAPI (owns the embedded Qdrant) + Streamlit together; # only the Streamlit UI (7860) is exposed publicly, the API (8000) is internal. FROM python:3.11-slim # HF Spaces runs as uid 1000. Create that user and give it a writable home. RUN useradd -m -u 1000 user ENV HOME=/home/user \ PATH=/home/user/.local/bin:$PATH \ PYTHONUNBUFFERED=1 \ HF_HOME=/home/user/.cache/huggingface \ PREBUILT_DIR=/home/user/app/app/prebuilt \ UI_PORT=7860 \ API_PORT=8000 USER user WORKDIR /home/user/app # Install deps first for layer caching. COPY --chown=user requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt # Source + shared core + corpus (prebuilt/ is gitignored and rebuilt below). COPY --chown=user src ./src COPY --chown=user app ./app COPY --chown=user data ./data COPY --chown=user scripts ./scripts # Bake the index into the image at build time (never empty on restart) and warm # the embedding model into the cache so the first request is fast. RUN python scripts/build_index.py \ && python -c "import sys; sys.path.insert(0,'src'); from streamsearch.embed import get_model; get_model()" EXPOSE 7860 CMD ["python", "app/dev.py"]