# ============================================================ # AuthorBot RAG API — HuggingFace Spaces Dockerfile # Entry: app.py → app/main.py (FastAPI) # Routes: /api/chat/{slug} · /api/admin/{slug} · /api/super · /health # ============================================================ FROM python:3.11-slim AS builder RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ libpq-dev \ libmagic1 \ curl \ git \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt # ── Production Stage ────────────────────────────────────────── FROM python:3.11-slim RUN apt-get update && apt-get install -y --no-install-recommends \ libpq5 \ libmagic1 \ curl \ redis-server \ && rm -rf /var/lib/apt/lists/* WORKDIR /app ENV PYTHONPATH=/app ENV DATABASE_URL=sqlite+aiosqlite:////data/db.sqlite ENV REDIS_URL=redis://:authorbotredis@localhost:6379/0 ENV CHROMA_CLIENT_MODE=persistent ENV CHROMA_PERSIST_DIR=/data/chroma ENV UPLOAD_STORAGE_PATH=/data/uploads COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # Copy entire flat project (app/, static/, app.py, requirements.txt) COPY app/ ./app/ COPY static/ ./static/ COPY app.py . RUN mkdir -p /data/chroma /data/uploads /data/sessions /data/redis && \ printf 'dir /data/redis\nbind 127.0.0.1\nport 6379\ndaemonize yes\nlogfile /dev/null\nrequirepass authorbotredis\nappendonly yes\nappendfsync everysec\n' > /app/redis-hf.conf RUN adduser --disabled-password --gecos "" --uid 1000 appuser && \ chown -R appuser:appuser /app /data USER appuser # Pre-warm ML models (non-fatal if network unavailable at build time) RUN python -c "from sentence_transformers import CrossEncoder; CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')" || true RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')" || true RUN python -c "from app.main import app; print('App import OK')" HEALTHCHECK --interval=30s --timeout=10s --start-period=180s --retries=5 \ CMD curl -f http://localhost:7860/health || exit 1 EXPOSE 7860 CMD ["sh", "-c", "mkdir -p /data/chroma /data/uploads /data/sessions /data/redis && redis-server /app/redis-hf.conf && sleep 1 && uvicorn app.main:app --host 0.0.0.0 --port 7860 --workers 1 --loop uvloop --http httptools"]