mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-25 20:53:55 +08:00
* Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Upgrade Firecrawl components to firecrawl-py v2 + add Search component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add Firecrawl Search API to the bundle page Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [autofix.ci] apply automated fixes * fix(firecrawl): D205 docstring + defensive .get('data') in crawl Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(firecrawl): D205 docstring in scrape Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * perf(firecrawl): use list.extend in map (PERF401) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: add unit tests for Firecrawl v2 components Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [autofix.ci] apply automated fixes * test: align Firecrawl component tests with lfx _attributes pattern Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [autofix.ci] apply automated fixes * refactor(firecrawl): remove deprecated extract endpoint component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(firecrawl): remove deprecated extract endpoint component Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: drop extract component test (extract endpoint removed) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: remove Firecrawl Extract API section (deprecated) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [autofix.ci] apply automated fixes * fix(firecrawl): map Search component to Firecrawl icon, drop Extract The frontend icon map in styleUtils.ts still referenced the removed FirecrawlExtractApi and lacked the new FirecrawlSearchApi, so the Search node would not render the Firecrawl logo. * chore: regenerate component index for Firecrawl v2 (Search added, Extract removed) * refactor(firecrawl): extract components into the lfx-firecrawl extension bundle Port the firecrawl provider out of lfx.components into a standalone Extension Bundle at src/bundles/firecrawl (distribution: lfx-firecrawl), following src/bundles/PORTING.md: - Move the v2-SDK components (Scrape, Crawl, Map, Search) to src/bundles/firecrawl/src/lfx_firecrawl/components/firecrawl/ and remove the in-tree provider + its lfx.components registration. - Own the firecrawl-py>=4,<5 pin in the bundle; drop it from langflow-base. - Wire the workspace (root pyproject deps/sources/members) and uv.lock. - Append migration-table entries (bare name, both import paths, pre-a slot) for the four classes; FirecrawlExtractApi gets no entries since the v2 SDK removed the extract endpoint and the component was dropped. - Regenerate the component index (firecrawl category removed) and locales/en.json (54 firecrawl keys move out of core). - Bundle-local unit tests + test_pilot_firecrawl_upgrade integration test; update Dockerfile bundle enumeration comments. * fix(lfx): repair migration table entry fused during release-1.11.0 merge The release-1.11.0 back-merge collided the FirecrawlSearchApi legacy_slot entry with the NextPlaidVectorStoreComponent bare_class_name entry, mashing both into a single object with duplicate 'target' keys, populating two of {bare_class_name, import_path, legacy_slot}. That fails the MigrationTable validator (entries.51) and broke the lfx loader tests. Split it into the two intended entries so each populates exactly one key-field. Restores the FirecrawlSearchApi and NextPlaidVectorStoreComponent quads (60 entries total, +16 vs base). Append-only and bare-name guards pass. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Hare <ericrhare@gmail.com>
116 lines
4.2 KiB
Docker
116 lines
4.2 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# Keep this syntax directive! It's used to enable Docker BuildKit
|
|
#
|
|
# Backend-only Langflow image
|
|
# - No frontend code or assets
|
|
# - No Playwright
|
|
|
|
################################
|
|
# BUILDER
|
|
################################
|
|
FROM ghcr.io/astral-sh/uv:python3.14-trixie-slim AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
# Required for apify-client
|
|
ENV RUSTFLAGS='--cfg reqwest_unstable'
|
|
|
|
# Install build dependencies
|
|
RUN apt-get update \
|
|
&& apt-get upgrade -y \
|
|
&& apt-get install --no-install-recommends -y \
|
|
build-essential \
|
|
gcc \
|
|
git \
|
|
curl \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy only backend source (excludes frontend)
|
|
COPY ./src/backend ./src/backend
|
|
COPY ./src/lfx ./src/lfx
|
|
COPY ./src/sdk ./src/sdk
|
|
|
|
# Create venv and install langflow-base with dependencies
|
|
# Using uv pip instead of uv sync to avoid workspace complexities
|
|
RUN uv venv /app/.venv
|
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
ENV VIRTUAL_ENV="/app/.venv"
|
|
|
|
# Install langflow-base with all extras except dev (which includes Playwright).
|
|
# This image ships the langflow-base core only. Extension bundles
|
|
# (lfx-duckduckgo, lfx-arxiv, lfx-ibm, lfx-docling, lfx-firecrawl) are intentionally NOT
|
|
# installed here -- they belong to the full ``langflow`` distribution, not
|
|
# the lean core. Use the ``langflow`` image, or ``pip install`` the bundle
|
|
# alongside this image, to add those components.
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv pip install \
|
|
./src/sdk \
|
|
./src/lfx \
|
|
"./src/backend/base[complete,postgresql]"
|
|
|
|
################################
|
|
# RUNTIME
|
|
################################
|
|
FROM python:3.14-slim-trixie AS runtime
|
|
|
|
# Install minimal runtime dependencies
|
|
RUN apt-get update \
|
|
&& apt-get upgrade -y \
|
|
&& apt-get install --no-install-recommends -y \
|
|
curl \
|
|
git \
|
|
libpq5 \
|
|
gnupg \
|
|
xz-utils \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
|
|
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
|
|
# Install Node.js (required for npx-based MCP stdio servers)
|
|
RUN ARCH=$(dpkg --print-architecture) \
|
|
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \
|
|
elif [ "$ARCH" = "arm64" ]; then NODE_ARCH="arm64"; \
|
|
else NODE_ARCH="$ARCH"; fi \
|
|
&& NODE_VERSION=$(curl -fsSL https://nodejs.org/dist/latest-v22.x/ \
|
|
| sed -nE "s/.*node-v([0-9]+\.[0-9]+\.[0-9]+)-linux-${NODE_ARCH}\.tar\.xz.*/\1/p" \
|
|
| head -1) \
|
|
&& if [ -z "$NODE_VERSION" ]; then echo "ERROR: Could not determine Node.js version" && exit 1; fi \
|
|
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \
|
|
| tar -xJ -C /usr/local --strip-components=1
|
|
|
|
# Create non-root user
|
|
RUN useradd --uid 1000 --gid 0 --no-create-home --home-dir /app/data user
|
|
|
|
# Copy only the virtual environment
|
|
COPY --from=builder --chown=1000:0 /app/.venv /app/.venv
|
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
|
|
# Create home directory and ensure proper ownership
|
|
# The user needs write access to /app/data (home) and /app (workdir).
|
|
# Also pre-create /app/langflow (LANGFLOW_CONFIG_DIR used by the docker_example
|
|
# compose file) with the non-root user as owner, so a fresh named volume mounted
|
|
# at /app/langflow inherits the correct ownership/permissions and the in-container
|
|
# uid=1000 user can write secret_key, profile_pictures, etc. Without this, the
|
|
# volume would be initialized as root:root and Langflow would crash with
|
|
# PermissionError on /app/langflow/secret_key (issue #10437).
|
|
# Note: .venv is already owned by 1000:0 via COPY --chown above, so no recursive chown needed
|
|
RUN mkdir -p /app/data /app/langflow \
|
|
&& chown -R 1000:0 /app/data /app/langflow \
|
|
&& chmod -R g+rwX /app/langflow \
|
|
&& chown 1000:0 /app
|
|
|
|
LABEL org.opencontainers.image.title=langflow-backend
|
|
LABEL org.opencontainers.image.authors=['Langflow']
|
|
LABEL org.opencontainers.image.licenses=MIT
|
|
LABEL org.opencontainers.image.url=https://github.com/langflow-ai/langflow
|
|
LABEL org.opencontainers.image.source=https://github.com/langflow-ai/langflow
|
|
|
|
USER user
|
|
WORKDIR /app
|
|
|
|
ENV LANGFLOW_HOST=0.0.0.0
|
|
ENV LANGFLOW_PORT=7860
|
|
|
|
CMD ["python", "-m", "langflow", "run", "--backend-only"]
|