# Hugging Face Spaces — Docker SDK router image. # Runs the unified router on port 7860 (HF's required port) as non-root. FROM python:3.11-slim # Create a non-root user (HF Spaces requires running as uid 1000). RUN useradd -m -u 1000 user WORKDIR /app # Install dependencies first (better Docker layer caching). COPY --chown=user requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt # Copy the source tree. models.json is a STUB here — the real config (with # keys) is fetched at runtime via the MODELS_URL env secret, so no keys ever # live in the public image. See scripts/deploy_hf.sh. COPY --chown=user src/ ./src/ RUN mkdir -p data && echo '{}' > data/models.json # Copy the dreamy website into static/ so FastAPI serves it at the same origin # (login.html, dashboard.html, css/, js/, assets/). COPY --chown=user static/ ./static/ # Switch to the non-root user for everything that follows. USER user # Environment variables for the non-root shell. ENV HOME=/home/user \ PATH=/home/user/.local/bin:$PATH \ PYTHONUNBUFFERED=1 # HF Spaces expects the app to listen on port 7860. EXPOSE 7860 # uvicorn serves src.app:app (module-level `app = create_app()`). # IMPORTANT: exactly ONE worker. This app is stateful (in-memory OAuth state, # balance cache, and background payment/tracker coroutines that credit users). # Multiple workers would split that state, race the same gists, and could # credit the same ETH deposit twice. cpu-basic handles our scale single-threaded. CMD ["uvicorn", "src.app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]