Spaces:
Running
Running
| # Build frontend | |
| FROM node:18 as frontend-build | |
| WORKDIR /app | |
| COPY frontend/package*.json ./ | |
| RUN npm install | |
| COPY frontend/ ./ | |
| RUN npm run build | |
| # Build backend | |
| FROM python:3.12-slim | |
| WORKDIR /app | |
| # Create non-root user | |
| RUN useradd -m -u 1000 user | |
| # Install poetry | |
| RUN pip install poetry | |
| # Create and configure cache directory | |
| RUN mkdir -p /app/.cache && \ | |
| chown -R user:user /app | |
| # Copy and install backend dependencies | |
| COPY backend/pyproject.toml backend/poetry.lock* ./ | |
| RUN poetry config virtualenvs.create false \ | |
| && poetry install --no-interaction --no-ansi --no-root --only main | |
| # Isolated venv for the eval worker (heavy ML deps: torch + braindecode from git), | |
| # kept OUT of the web app's pinned stack to avoid version conflicts. Built before | |
| # the code COPY so it stays cached across code-only rebuilds. Non-fatal: if the | |
| # install fails, the web app still builds and the worker is simply disabled. | |
| RUN apt-get update && apt-get install -y --no-install-recommends git \ | |
| && python -m venv /opt/worker-venv \ | |
| && /opt/worker-venv/bin/pip install --no-cache-dir -U pip \ | |
| && (/opt/worker-venv/bin/pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu \ | |
| && /opt/worker-venv/bin/pip install --no-cache-dir huggingface_hub pandas pyarrow open-eeg-bench \ | |
| || echo "WARN: eval-worker deps failed to install; worker disabled at runtime") \ | |
| && chown -R user:user /opt/worker-venv \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Copy backend code | |
| COPY backend/ . | |
| # Install Node.js and npm | |
| RUN apt-get update && apt-get install -y \ | |
| curl \ | |
| netcat-openbsd \ | |
| && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ | |
| && apt-get install -y nodejs \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Copy frontend server and build | |
| COPY --from=frontend-build /app/build ./frontend/build | |
| COPY --from=frontend-build /app/package*.json ./frontend/ | |
| COPY --from=frontend-build /app/server.js ./frontend/ | |
| # Install frontend production dependencies | |
| WORKDIR /app/frontend | |
| RUN npm install --production | |
| WORKDIR /app | |
| # Environment variables | |
| ENV HF_HOME=/app/.cache \ | |
| HF_DATASETS_CACHE=/app/.cache \ | |
| INTERNAL_API_PORT=7861 \ | |
| PORT=7860 \ | |
| NODE_ENV=production \ | |
| RUN_EVAL_WORKER=1 | |
| # Note: HF_TOKEN should be provided at runtime, not build time | |
| USER user | |
| EXPOSE 7860 | |
| # Start the API, the (optional) CPU eval worker, and the frontend. The worker | |
| # runs in its own venv as a background --watch loop. Disable it without a rebuild | |
| # by setting RUN_EVAL_WORKER=0 in the Space settings, then restarting. | |
| CMD ["sh", "-c", "uvicorn app.asgi:app --host 0.0.0.0 --port 7861 & if [ \"$RUN_EVAL_WORKER\" = \"1\" ]; then PYTHONPATH=/app /opt/worker-venv/bin/python -m scripts.run_eval_worker --watch --limit 1 --interval 300 --device cpu & fi; while ! nc -z localhost 7861; do sleep 1; done && cd frontend && npm run serve"] | |