Spaces:
Running
Running
File size: 5,997 Bytes
b73c012 5d8d23e c13c2a7 5d8d23e 45fe8f0 6a3762e 5d8d23e 45fe8f0 5d8d23e 45fe8f0 5d8d23e 45fe8f0 5d8d23e 45fe8f0 5d8d23e 45fe8f0 5d8d23e b6e5beb 6cd3e11 45fe8f0 6cd3e11 5d8d23e 45fe8f0 6cd3e11 5d8d23e 45fe8f0 5d8d23e 45fe8f0 5d8d23e c13c2a7 45fe8f0 6a3762e 5d8d23e b6e5beb 5d8d23e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | # syntax=docker/dockerfile:1
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# HuggingFlow β DeerFlow Research Agent for Hugging Face Spaces
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#
# Uses official pre-built DeerFlow images from GHCR β no compile step.
# Build time: ~5 min (was 30+ min building from source).
#
# Public port 7860 β health-server.js β nginx:7861 β backend:8001 / frontend:3000
#
# Build args:
# DEERFLOW_BACKEND β backend image (default: ghcr.io/bytedance/deer-flow-backend:latest)
# DEERFLOW_FRONTEND β frontend image (default: ghcr.io/bytedance/deer-flow-frontend:latest)
# UV_IMAGE β uv tool image (default: ghcr.io/astral-sh/uv:0.7.20)
# NODE_MAJOR β Node.js major version (default: 22)
ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.7.20
ARG DEERFLOW_BACKEND=ghcr.io/bytedance/deer-flow-backend:latest
ARG DEERFLOW_FRONTEND=ghcr.io/bytedance/deer-flow-frontend:latest
# ββ uv source ββββββββββββββββββββββββββββββββββββββββββββββββββββ
FROM ${UV_IMAGE} AS uv-source
# ββ Pre-built DeerFlow images (no source compilation needed) ββββββ
# Backend image layout: /app/backend/ (Python source + .venv)
# Frontend image layout: /app/frontend/ (built .next + node_modules)
FROM ${DEERFLOW_BACKEND} AS backend-src
FROM ${DEERFLOW_FRONTEND} AS frontend-src
# ββ Minimal source clone (skills + config only) βββββββββββββββββββ
# skills/ and config.example.yaml are not bundled in the official images
FROM alpine/git:latest AS source
RUN git clone --depth=1 \
https://github.com/bytedance/deer-flow.git /src && \
cd /src && \
git log --oneline -1
# ββ Runtime βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
FROM python:3.12-slim-bookworm
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
PYTHONIOENCODING=utf-8 \
PYTHONUNBUFFERED=1
ARG NODE_MAJOR=22
# Layer 1: nginx + base tools (rarely changes β stays cached)
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates gnupg nginx openssl \
&& rm -rf /var/lib/apt/lists/*
# Layer 2: Node.js (separate layer β apt network stall doesn't force pip re-run)
RUN mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] \
https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \
> /etc/apt/sources.list.d/nodesource.list \
&& apt-get update && apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# Layer 3: Python helpers with retries (flaky HF Spaces network)
RUN pip3 install --no-cache-dir --break-system-packages --timeout 120 --retries 5 \
huggingface_hub pyyaml \
|| (echo "pip retry 2" && pip3 install --no-cache-dir --break-system-packages --timeout 120 --retries 5 huggingface_hub pyyaml) \
|| (echo "pip retry 3" && pip3 install --no-cache-dir --break-system-packages --timeout 120 --retries 5 huggingface_hub pyyaml) \
|| (echo "ERROR: pip install failed after 3 attempts" && exit 1)
# pnpm for `pnpm start` in Next.js runtime
RUN corepack enable && corepack install -g pnpm@10.26.2
# uv for backend startup (`uv run --no-sync uvicorn ...`)
COPY --from=uv-source /uv /uvx /usr/local/bin/
# ββ Create non-root user UID=1000 (required by HF Spaces) ββββββββ
RUN useradd -m -u 1000 -s /bin/bash user && \
mkdir -p \
/app/backend \
/app/frontend \
/app/skills \
/app/data \
/tmp/nginx-tmp && \
chown -R 1000:1000 /app /tmp/nginx-tmp && \
chown -R 1000:1000 /var/log/nginx /var/lib/nginx 2>/dev/null || true
# ββ Copy pre-built DeerFlow artifacts ββββββββββββββββββββββββββββ
# Backend: Python source + pre-built .venv (no uv sync / grpcio compile)
COPY --from=backend-src --chown=1000:1000 /app/backend /app/backend
# Frontend: built .next + node_modules (no pnpm install / Next.js build)
COPY --from=frontend-src --chown=1000:1000 /app/frontend /app/frontend
# Skills (not bundled in official images)
COPY --from=source --chown=1000:1000 /src/skills /app/skills
# Config template
COPY --from=source --chown=1000:1000 /src/config.example.yaml /app/config.example.yaml
# ββ Copy HuggingFlow runtime scripts βββββββββββββββββββββββββββββ
COPY --chown=1000:1000 nginx.conf /etc/nginx/nginx.conf
COPY --chown=1000:1000 start.sh /app/start.sh
COPY --chown=1000:1000 deerflow-sync.py /app/deerflow-sync.py
COPY --chown=1000:1000 health-server.js /app/health-server.js
COPY --chown=1000:1000 cloudflare-proxy.js /app/cloudflare-proxy.js
COPY --chown=1000:1000 cloudflare-proxy-setup.py /app/cloudflare-proxy-setup.py
COPY --chown=1000:1000 cloudflare-keepalive-setup.py /app/cloudflare-keepalive-setup.py
RUN chmod +x \
/app/start.sh \
/app/deerflow-sync.py \
/app/cloudflare-proxy-setup.py \
/app/cloudflare-keepalive-setup.py
USER user
WORKDIR /app
EXPOSE 7860
# 120s start period β restore + backend + frontend startup can take up to 2 min
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s \
CMD curl -fsS http://localhost:7860/health || exit 1
CMD ["/app/start.sh"]
|