Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: dockerfile with entrypoint #4062

Merged
merged 6 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 59 additions & 21 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
version:
required: false
type: string
description: "Main version to build. Does not support base version."
release_type:
required: true
type: string
Expand All @@ -26,7 +27,7 @@ on:
workflow_dispatch:
inputs:
version:
description: "Version to build"
description: "Main version to build. Does not support base version."
required: false
type: string
release_type:
Expand Down Expand Up @@ -101,18 +102,49 @@ jobs:
with:
ref: ${{ inputs.nightly_tag_main || github.ref }}
persist-credentials: true
- name: "Setup Environment"
uses: ./.github/actions/setup-uv
- name: Install the project
run: uv sync --dev

- name: Get Version from Input
if: ${{ inputs.version != '' }}
id: get-version-input
run: |
version=${{ inputs.version }}
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
# Base version cannot have a version input, since you have to specify a valid main tag to checkout.
if [[ "${{ inputs.release_type }}" == "base" && "${{ inputs.version }}" != '' ]]; then
echo "Cannot specify version for base release."
echo "Build type is 'base' and version is non-empty. Exiting the workflow."
exit 1
fi
# If doing a nightly release, just specify the nightly tag.
if [[ "${{ inputs.version }}" != '' && "${{ steps.resolve-nightly-tag.outputs.nightly-tag }}" != '' ]]; then
echo "Cannot specify both version and nightly version."
echo "Version is specified and nightly tag is non-empty. Exiting the workflow."
exit 1
fi
if [[ "${{ steps.resolve-nightly-tag.outputs.nightly-tag }}" != '' ]]; then
if [[ "${{ inputs.nightly_tag_main }}" == '' ]]; then
echo "Must specify a main nightly tag to check out when building base image."
echo "Nightly tag main is empty. Exiting the workflow."
exit 1
fi
echo "main nightly version=${{ inputs.nightly_tag_main }}"
echo "base nightly version=${{ inputs.nightly_tag_base }}"
echo "building image for nightly_version=${{ steps.resolve-nightly-tag.outputs.nightly-tag }}"
# Strip leading v from nightly tag main if present
version=${{ inputs.nightly_tag_main }}
version=${version#v}
echo version=$version >> $GITHUB_OUTPUT
elif [[ "${{ inputs.version }}" != '' ]]; then
# strip leading v if present
version=${{ inputs.version }}
version=${version#v}
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
else
echo "No version or ref specified. Exiting the workflow."
exit 1
fi
- name: Get Version Base
if: ${{ inputs.version == '' && inputs.release_type == 'base' }}
id: get-version-base
Expand All @@ -121,7 +153,7 @@ jobs:
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
- name: Get Version Main
if: ${{ inputs.version == '' && inputs.release_type == 'main' }}
if: ${{ inputs.version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep') }}
id: get-version-main
run: |
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
Expand All @@ -135,11 +167,6 @@ jobs:
ghcr_tags: ${{ steps.set-vars.outputs.ghcr_tags }}
file: ${{ steps.set-vars.outputs.file }}
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v4
with:
ref: ${{ inputs.nightly_tag_main || github.ref }}

- name: Set Dockerfile and Tags
id: set-vars
run: |
Expand All @@ -149,18 +176,30 @@ jobs:
fi
if [[ "${{ inputs.release_type }}" == "base" ]]; then
# LANGFLOW-BASE RELEASE
echo "docker_tags=langflowai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_base.Dockerfile" >> $GITHUB_OUTPUT
else
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
# LANGFLOW-MAIN PRE-RELEASE
echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
else
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main-ep" ]]; then
# LANGFLOW-MAIN (ENTRYPOINT) RELEASE
echo "docker_tags=langflowai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_ep.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main" ]]; then
# LANGFLOW-MAIN RELEASE
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
else
echo "Invalid release type. Exiting the workflow."
exit 1
fi
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
fi
build:
runs-on: ubuntu-latest
Expand All @@ -169,15 +208,14 @@ jobs:
- name: Check out the code at a specific ref
uses: actions/checkout@v4
with:
ref: ${{ inputs.nightly_tag_main || github.ref }}
ref: ${{ needs.get-version.outputs.version || github.ref }}
persist-credentials: true
- name: "Setup Environment"
uses: ./.github/actions/setup-uv

- name: Install the project
run: |
if [[ "${{ inputs.release_type }}" == "base" ]]; then
cd src/backend/base && uv sync --no-dev --no-sources
uv sync --directory src/backend/base --no-dev --no-sources
else
uv sync --no-dev --no-sources
fi
Expand Down Expand Up @@ -246,7 +284,7 @@ jobs:
- name: Check out the code at a specific ref
uses: actions/checkout@v4
with:
ref: ${{ inputs.nightly_tag_main || github.ref }}
ref: ${{ needs.get-version.outputs.version || github.ref }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand Down Expand Up @@ -294,7 +332,7 @@ jobs:
- name: Check out the code at a specific ref
uses: actions/checkout@v4
with:
ref: ${{ inputs.nightly_tag_main || github.ref }}
ref: ${{ needs.get-version.outputs.version || github.ref }}
- name: "Setup Environment"
uses: ./.github/actions/setup-uv

Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ on:
required: true
type: boolean
default: false
build_docker_ep:
description: "Build Docker Image for Langflow with Entrypoint"
required: false
type: boolean
default: false
pre_release:
description: "Pre-release"
required: false
Expand Down Expand Up @@ -203,6 +208,16 @@ jobs:
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
uses: ./.github/workflows/docker-build.yml
with:
version: needs.release-main.outputs.version
release_type: main-ep
pre_release: False
secrets: inherit

create_release:
name: Create Release
runs-on: ubuntu-latest
Expand Down
26 changes: 22 additions & 4 deletions .github/workflows/release_nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ on:
required: true
type: boolean
default: false
build_docker_ep:
description: "Build Docker Image for Langflow Nightly with Entrypoint"
required: false
type: boolean
default: false
nightly_tag_main:
description: "Tag for the nightly main build"
required: true
Expand All @@ -34,6 +39,11 @@ on:
required: true
type: boolean
default: false
build_docker_ep:
description: "Build Docker Image for Langflow Nightly with Entrypoint"
required: false
type: boolean
default: false
nightly_tag_main:
description: "Tag for the nightly main build"
required: true
Expand Down Expand Up @@ -197,8 +207,6 @@ jobs:
needs: [release-nightly-base, release-nightly-main]
uses: ./.github/workflows/docker-build.yml
with:
# Version should _not_ contain the leading `v`
version: ${{ needs.release-nightly-base.outputs.version }}
release_type: base
nightly_tag_base: ${{ inputs.nightly_tag_base }}
nightly_tag_main: ${{ inputs.nightly_tag_main }}
Expand All @@ -210,10 +218,20 @@ jobs:
needs: [release-nightly-main]
uses: ./.github/workflows/docker-build.yml
with:
# Version should _not_ contain the leading `v`
version: ${{ needs.release-nightly-main.outputs.version }}
release_type: main
nightly_tag_main: ${{ 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' }}
needs: [release-nightly-main]
uses: ./.github/workflows/docker-build.yml
with:
release_type: main-ep
nightly_tag_main: ${{ inputs.nightly_tag_main }}
secrets: inherit




91 changes: 91 additions & 0 deletions docker/build_and_push_ep.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# 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 install --no-install-recommends -y \
# deps for building python deps
build-essential \
# 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

ADD ./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
ADD ./pyproject.toml /app/pyproject.toml
ADD ./uv.lock /app/uv.lock
ADD ./README.md /app/README.md

RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-editable

################################
# RUNTIME
# Setup user, utilities and copy the virtual environment only
################################
FROM python:3.12.3-slim AS runtime

RUN 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

RUN useradd ragstack -u 10000 -g 0 --no-create-home --home-dir /app/data
WORKDIR /app

RUN mkdir /data
RUN chown -R 10000:0 /data
RUN chown -R 10000:0 /app

ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860

USER 10000

ENTRYPOINT ["python", "-m", "langflow", "run", "--host", "0.0.0.0", "--backend-only"]
Loading