diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 7c4976c59..8ae7964fc 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -14,7 +14,7 @@ on: release_type: required: true type: string - description: "Release type. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'." + description: "Release type. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base', 'main-all', 'nightly-main-all'." pre_release: required: false type: boolean @@ -35,7 +35,7 @@ on: required: false type: string release_type: - description: "Type of release. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'." + description: "Type of release. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base', 'main-all', 'nightly-main-all'." required: true type: string pre_release: @@ -88,7 +88,7 @@ jobs: exit 1 fi - if [[ "${{ inputs.release_type }}" == "main" && "${{ inputs.main_version }}" == '' ]]; then + if [[ ("${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "main-all") && "${{ inputs.main_version }}" == '' ]]; then echo "Must specify a main version for main release type." exit 1 fi @@ -98,7 +98,7 @@ jobs: exit 1 fi - if [[ "${{ inputs.release_type }}" == "nightly-main" && "${{ inputs.main_version }}" == '' ]]; then + if [[ ("${{ inputs.release_type }}" == "nightly-main" || "${{ inputs.release_type }}" == "nightly-main-all") && "${{ inputs.main_version }}" == '' ]]; then echo "Must specify a main version for nightly-main release type." exit 1 fi @@ -128,7 +128,7 @@ jobs: echo version=$version echo version=$version >> $GITHUB_OUTPUT - name: Get Version Main - if: ${{ inputs.main_version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep' || inputs.release_type == 'nightly-main') }} + if: ${{ inputs.main_version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep' || inputs.release_type == 'nightly-main' || inputs.release_type == 'main-all' || inputs.release_type == 'nightly-main-all') }} id: get-version-main run: | version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//') @@ -146,7 +146,7 @@ jobs: id: set-vars run: | nightly_suffix='' - if [[ "${{ inputs.release_type }}" == "nightly-base" || "${{ inputs.release_type }}" == "nightly-main" ]]; then + if [[ "${{ inputs.release_type }}" == "nightly-base" || "${{ inputs.release_type }}" == "nightly-main" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then nightly_suffix="-nightly" fi @@ -171,6 +171,11 @@ jobs: echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT + elif [[ "${{ inputs.release_type }}" == "main-all" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then + # LANGFLOW-MAIN (ALL OPTIONAL DEPS) RELEASE + echo "docker_tags=langflowai/langflow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT + echo "ghcr_tags=ghcr.io/langflow-ai/langflow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT + echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT else echo "Invalid release type. Exiting the workflow." exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b05a03a5..074ec6c3d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -211,6 +211,17 @@ jobs: pre_release: ${{ inputs.pre_release }} secrets: inherit + call_docker_build_main_all: + name: Call Docker Build Workflow for Langflow + if: inputs.build_docker_main == true + needs: [release-main] + uses: ./.github/workflows/docker-build.yml + with: + main_version: ${{ needs.release-main.outputs.version }} + release_type: main-all + pre_release: ${{ inputs.pre_release }} + secrets: inherit + call_docker_build_main_ep: name: Call Docker Build Workflow for Langflow with Entrypoint if: inputs.build_docker_ep == true diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml index 8e15162aa..b07615cf6 100644 --- a/.github/workflows/release_nightly.yml +++ b/.github/workflows/release_nightly.yml @@ -225,6 +225,17 @@ jobs: main_version: ${{ inputs.nightly_tag_main }} secrets: inherit + call_docker_build_main_all: + name: Call Docker Build Workflow for Langflow + if: always() && ${{ inputs.build_docker_main == 'true' }} + needs: [release-nightly-main] + uses: ./.github/workflows/docker-build.yml + with: + release_type: nightly-main-all + main_version: ${{ inputs.nightly_tag_main }} + secrets: inherit + + call_docker_build_main_ep: name: Call Docker Build Workflow for Langflow with Entrypoint if: always() && ${{ inputs.build_docker_ep == 'true' }} diff --git a/docker/build_and_push_with_extras.Dockerfile b/docker/build_and_push_with_extras.Dockerfile new file mode 100644 index 000000000..36acd416e --- /dev/null +++ b/docker/build_and_push_with_extras.Dockerfile @@ -0,0 +1,95 @@ +# syntax=docker/dockerfile:1 +# Keep this syntax directive! It's used to enable Docker BuildKit + +################################ +# BUILDER-BASE +# Used to build deps + create our virtual environment +################################ + +# 1. use python:3.12.3-slim as the base image until https://github.com/pydantic/pydantic-core/issues/1292 gets resolved +# 2. do not add --platform=$BUILDPLATFORM because the pydantic binaries must be resolved for the final architecture +# Use a Python image with uv pre-installed +FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder + +# Install the project into `/app` +WORKDIR /app + +# Enable bytecode compilation +ENV UV_COMPILE_BYTECODE=1 + +# Copy from the cache instead of linking since it's a mounted volume +ENV UV_LINK_MODE=copy + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install --no-install-recommends -y \ + # deps for building python deps + build-essential \ + git \ + # npm + npm \ + # gcc + gcc \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN --mount=type=cache,target=/root/.cache/uv \ + --mount=type=bind,source=uv.lock,target=uv.lock \ + --mount=type=bind,source=README.md,target=README.md \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + --mount=type=bind,source=src/backend/base/README.md,target=src/backend/base/README.md \ + --mount=type=bind,source=src/backend/base/uv.lock,target=src/backend/base/uv.lock \ + --mount=type=bind,source=src/backend/base/pyproject.toml,target=src/backend/base/pyproject.toml \ + uv sync --frozen --no-install-project --no-editable --extra deploy --extra couchbase --extra cassio --extra local --extra clickhouse-connect --extra nv-ingest --extra postgresql + +COPY ./src /app/src + +COPY src/frontend /tmp/src/frontend +WORKDIR /tmp/src/frontend +RUN --mount=type=cache,target=/root/.npm \ + npm ci \ + && npm run build \ + && cp -r build /app/src/backend/langflow/frontend \ + && rm -rf /tmp/src/frontend + +WORKDIR /app +COPY ./pyproject.toml /app/pyproject.toml +COPY ./uv.lock /app/uv.lock +COPY ./README.md /app/README.md + +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --frozen --no-editable --extra deploy --extra couchbase --extra cassio --extra local --extra clickhouse-connect --extra nv-ingest --extra postgresql + +################################ +# RUNTIME +# Setup user, utilities and copy the virtual environment only +################################ +FROM python:3.12.3-slim AS runtime + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y curl git libpq5 gnupg \ + && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && useradd user -u 1000 -g 0 --no-create-home --home-dir /app/data + +COPY --from=builder --chown=1000 /app/.venv /app/.venv + +# Place executables in the environment at the front of the path +ENV PATH="/app/.venv/bin:$PATH" + +LABEL org.opencontainers.image.title=langflow +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 ["langflow", "run"]