FROM python:3.12-slim RUN useradd -m -u 1000 user USER user ENV HOME=/home/user \ PATH=/home/user/.local/bin:$PATH \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ ENCODE_DEVICE=cpu \ ENCODE_RUNTIME_DIR=/home/user/app/outputs/runtime \ ENCODE_CODE_INDEX_DIR=/home/user/app/outputs/indexes/bge_ft_va \ ENCODE_MODEL_DIR=/home/user/app/outputs/models/bge_ft_va \ ENCODE_PARTA_MODEL=/home/user/app/outputs/models/bge_ft_va \ ENCODE_PARTA_EMB_DIR=/home/user/app/outputs/embeddings/bge_ft_va \ OMP_NUM_THREADS=2 \ OPENBLAS_NUM_THREADS=2 \ MKL_NUM_THREADS=2 \ TOKENIZERS_PARALLELISM=false \ HF_HUB_DISABLE_TELEMETRY=1 # Submitted labels are the only runtime write, and /tmp dies with the container. # This path is a read-write bucket mount (hf spaces volumes ls), so labels outlive # every restart. Its own instruction: a comment cannot sit inside the ENV block # above, where an indented # is an argument rather than a comment. ENV ENCODE_ANNOT_DIR=/home/user/app/annotations WORKDIR $HOME/app # Both bucket mount points exist in the image before the mounts land on # them; hf-mount fails on a missing directory. RUN mkdir -p ./outputs ./annotations COPY --chown=user src/requirements.txt ./requirements.txt RUN python -m pip install --no-cache-dir --upgrade pip && \ python -m pip install --no-cache-dir \ --index-url https://download.pytorch.org/whl/cpu "torch==2.13.0" && \ python -m pip install --no-cache-dir -r requirements.txt COPY --chown=user src ./src EXPOSE 7860 STOPSIGNAL SIGTERM HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:7860/healthz', timeout=2).read()" CMD ["uvicorn", "src.backend.app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]