Spaces:
Running
Running
AuthorBot
Production hardening: JWT blacklist, TOTP, Pydantic schemas, Prometheus, SSRF fix, CSP, Redis auth, Celery backup β 35 items across P0-P5
131d826 | # ============================================================ | |
| # 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"] | |