# OptETF — Hugging Face Spaces(Docker SDK)部署用 Dockerfile # 使用方式:把本檔(連同 README.md / .dockerignore / requirements-hf.txt)放到 # Hugging Face Space repo 的「根目錄」,build context = repo 根目錄。 FROM python:3.10-slim # 系統相依:git(部分套件安裝需要)、fonts-noto-cjk(matplotlib 圖表中文字型, # 否則 Linux 容器缺中文字型,圖中中文會變空白方塊並噴 findfont 警告)。 RUN apt-get update && apt-get install -y --no-install-recommends \ git build-essential fonts-noto-cjk && \ rm -rf /var/lib/apt/lists/* ENV PYTHONUNBUFFERED=1 \ MPLBACKEND=Agg \ HF_HOME=/app/.cache/huggingface \ ETF_SERVER_MODE=1 \ PORT=7860 \ TOKENIZERS_PARALLELISM=false WORKDIR /app # 1) 先裝相依(善用 Docker layer 快取)。torch 用 CPU 版(較小、Spaces 免費層為 CPU)。 COPY requirements-hf.txt /app/requirements-hf.txt RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu && \ pip install --no-cache-dir -r /app/requirements-hf.txt # 2) 預先把 BGE-M3(~2.2GB)下載並烤進映像,避免每次冷啟動重抓 RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('BAAI/bge-m3')" # 3) 複製專案程式與既有快取(.dockerignore 已排除 model/dist/zip/.git 等) COPY . /app # 4) 執行期需要可寫的輸出目錄(Spaces 預設以非 root 使用者執行) RUN mkdir -p /app/user_results /app/csv /app/json /app/.cache && \ chmod -R 777 /app/user_results /app/csv /app/json /app/.cache EXPOSE 7860 # 單一 worker(共用全域偏好會話狀態,避免多 worker 切分請求導致會話錯亂)+多執行緒; # timeout 0:長流程(pipeline/回測)在背景執行緒執行,避免被 worker timeout 砍掉。 CMD ["gunicorn", "-w", "1", "--threads", "8", "-b", "0.0.0.0:7860", "--timeout", "0", "etf_web.app:app"]