FROM node:20-slim AS frontend-builder WORKDIR /app/frontend COPY upstream-open-notebook/frontend/package.json upstream-open-notebook/frontend/package-lock.json ./ ARG NPM_REGISTRY=https://registry.npmjs.org/ RUN npm config set registry ${NPM_REGISTRY} \ && npm config set fetch-retries 5 \ && npm config set fetch-retry-mintimeout 20000 \ && npm config set fetch-retry-maxtimeout 120000 RUN i=0; until npm ci; do \ i=$((i+1)); \ if [ "$i" -ge 5 ]; then echo "npm ci failed after $i attempts"; exit 1; fi; \ echo "npm ci failed (attempt $i); retrying in 15s"; sleep 15; \ done COPY upstream-open-notebook/frontend/ ./ RUN npm run build FROM surrealdb/surrealdb:v2 AS surreal-binary FROM python:3.12-slim-bookworm AS backend-builder RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends \ build-essential \ && rm -rf /var/lib/apt/lists/* COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ WORKDIR /app ENV UV_HTTP_TIMEOUT=120 COPY upstream-open-notebook/pyproject.toml upstream-open-notebook/uv.lock ./ COPY upstream-open-notebook/open_notebook/__init__.py ./open_notebook/__init__.py RUN uv sync --frozen --no-dev COPY upstream-esperanto /opt/esperanto RUN uv pip install --python /app/.venv/bin/python --no-cache --reinstall-package esperanto --no-deps /opt/esperanto ENV TIKTOKEN_CACHE_DIR=/app/tiktoken-cache RUN mkdir -p /app/tiktoken-cache && \ .venv/bin/python -c "import tiktoken; tiktoken.get_encoding('o200k_base')" FROM python:3.12-slim-bookworm AS runtime RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends \ bash \ curl \ ffmpeg \ git \ git-lfs \ procps \ supervisor \ wget \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* COPY --from=surreal-binary /surreal /usr/local/bin/surreal COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ WORKDIR /app COPY --from=backend-builder /app/.venv /app/.venv COPY upstream-open-notebook /app COPY --from=backend-builder /opt/esperanto /opt/esperanto RUN uv pip install --python /app/.venv/bin/python --no-cache --reinstall-package esperanto --no-deps /opt/esperanto COPY --from=backend-builder /app/tiktoken-cache /app/tiktoken-cache COPY --from=frontend-builder /app/frontend/.next/standalone /app/frontend/ COPY --from=frontend-builder /app/frontend/.next/static /app/frontend/.next/static COPY --from=frontend-builder /app/frontend/public /app/frontend/public COPY start-hf.sh /start-hf.sh RUN chmod +x /start-hf.sh && chmod +x /app/scripts/wait-for-api.sh COPY upstream-open-notebook/supervisord.single.conf /etc/supervisor/conf.d/supervisord.conf RUN mkdir -p /app/data /mydata /var/log/supervisor ENV HOSTNAME=0.0.0.0 ENV SURREAL_URL=ws://localhost:8000/rpc ENV SURREAL_USER=root ENV SURREAL_PASSWORD=root ENV SURREAL_NAMESPACE=open_notebook ENV SURREAL_DATABASE=open_notebook ENV INTERNAL_API_URL=http://localhost:5055 ENV TIKTOKEN_CACHE_DIR=/app/tiktoken-cache ENV LOG_LEVEL=INFO ENV RUST_LOG=warn EXPOSE 8502 5055 CMD ["/start-hf.sh"]