| # Stage 1: Build the React/Vite frontend |
| FROM node:20-slim AS fe |
| WORKDIR /fe |
| COPY frontend/package*.json ./ |
| RUN npm ci |
| COPY frontend/ ./ |
| RUN npm run build |
|
|
| # Stage 2: Python runtime |
| FROM python:3.11-slim |
|
|
| # Copy uv binary from the official uv image |
| COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ |
|
|
| WORKDIR /app |
|
|
| # Copy dependency manifests and install Python deps (no project install needed |
| # since pyproject.toml declares this as a virtual package) |
| COPY backend/pyproject.toml backend/uv.lock ./backend/ |
| WORKDIR /app/backend |
| RUN uv sync --frozen --no-dev |
|
|
| # Copy the rest of the backend source |
| COPY backend/ /app/backend/ |
|
|
| # Copy the built frontend into the image |
| COPY --from=fe /fe/dist /app/frontend/dist |
|
|
| # Runtime environment variables |
| ENV BEACON_STATIC_DIR=/app/frontend/dist \ |
| ASTROPARSE_CORPUS_DIR=/data/corpus \ |
| ASTROPARSE_FAISS_PATH=/data/astroparse_fp16.faiss \ |
| ASTROPARSE_FIGURES_DIR=/data/figures \ |
| ASTROPARSE_CACHE_PATH=/data/annotations_cache.sqlite \ |
| HF_HOME=/data/hf_cache |
|
|
| # HF Spaces mounts a writable /data volume; ensure it exists and is writable |
| # by any user (HF Spaces runs containers as uid 1000, not root) |
| RUN mkdir -p /data && chmod 777 /data |
|
|
| EXPOSE 7860 |
|
|
| CMD ["uv", "run", "--no-sync", "uvicorn", "astroparse_api.main:app", "--host", "0.0.0.0", "--port", "7860"] |
|
|