Spaces:
Running
Running
| # Single-container Hugging Face Space image for 9XAIPal. | |
| # The container starts PostgreSQL (with pgvector) + Redis in the background and | |
| # then launches the plain FastAPI app (app.py) on port 7860 via supervisord. | |
| # Pin to Debian bookworm: the PGDG apt repo below targets bookworm, and the | |
| # default python:3.11-slim now resolves to Debian trixie (libicu76/libldap-2.6), | |
| # whose libs can't satisfy the bookworm PostgreSQL packages. | |
| FROM python:3.11-slim-bookworm | |
| ENV PYTHONDONTWRITEBYTECODE=1 \ | |
| PYTHONUNBUFFERED=1 \ | |
| # Tell uvicorn to bind on 0.0.0.0 by default. | |
| HOST=0.0.0.0 \ | |
| PORT=7860 \ | |
| # Default paths inside the container. | |
| UI_DIR=/code/dist \ | |
| # In-container Ollama (embeddings only): bind locally and store the baked | |
| # model where both build-time pull and runtime serve will look for it. | |
| OLLAMA_HOST=127.0.0.1:11434 \ | |
| OLLAMA_MODELS=/root/.ollama/models \ | |
| # The Space image does not bake MinerU (several GB). Enable the PyMuPDF | |
| # text-only fallback so uploads still process out of the box; install MinerU | |
| # and set this to 0 for higher-fidelity extraction. | |
| ALLOW_PYMUPDF_FALLBACK=1 | |
| WORKDIR /code | |
| # Install Redis, PostgreSQL 16 + pgvector, and basic build tooling. | |
| # - Redis is required by the backend Celery queue. | |
| # - PostgreSQL (with the pgvector extension) is the app's primary database; | |
| # it runs inside this container and is created/initialized by start.sh. | |
| # - build-essential/libpq-dev are here in case a dependency wheel is | |
| # unavailable for the current platform. | |
| # PostgreSQL + pgvector come from the official PGDG apt repository. | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| ca-certificates curl gnupg \ | |
| zstd \ | |
| redis-server \ | |
| supervisor \ | |
| build-essential \ | |
| libpq-dev \ | |
| && install -d /usr/share/postgresql-common/pgdg \ | |
| && curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \ | |
| -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \ | |
| && echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" \ | |
| > /etc/apt/sources.list.d/pgdg.list \ | |
| && apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| postgresql-16 \ | |
| postgresql-16-pgvector \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Install Ollama and bake the embedding model into the image. Chat runs on | |
| # Ollama Cloud (a 31B model), but the cloud doesn't host embedding models, so we | |
| # serve qwen3-embedding from an in-container Ollama at localhost:11434. Pulling | |
| # the weights at build time bakes them into an image layer, so cold starts don't | |
| # re-download ~640 MB and the Space works even without a persistent disk. | |
| RUN curl -fsSL https://ollama.com/install.sh | sh \ | |
| && (ollama serve & srv=$!; \ | |
| for i in $(seq 1 30); do ollama list >/dev/null 2>&1 && break; sleep 1; done; \ | |
| ollama pull qwen3-embedding; \ | |
| kill "$srv" 2>/dev/null || true) | |
| # Install Python dependencies first so layer caching works across code changes. | |
| COPY requirements.txt . | |
| RUN pip install --no-cache-dir --upgrade pip \ | |
| && pip install --no-cache-dir -r requirements.txt | |
| # Copy the rest of the project (backend code, tests, and the React dist build). | |
| COPY . . | |
| COPY supervisord.conf /code/supervisord.conf | |
| RUN chmod +x /code/start.sh | |
| EXPOSE 7860 | |
| # Docker will restart the container if /healthz starts returning unhealthy. | |
| # start.sh brings up PostgreSQL (+pgvector), Redis and Ollama, then supervisord | |
| # keeps the API + Celery worker alive. | |
| HEALTHCHECK --interval=30s --timeout=15s --start-period=120s --retries=4 \ | |
| CMD curl -fsS http://127.0.0.1:7860/healthz >/dev/null || exit 1 | |
| CMD ["bash", "/code/start.sh"] | |