Skip to content

Commit

Permalink
build: dockerfile with entrypoint (#4062)
Browse files Browse the repository at this point in the history
Adds a dockerfile with an entrypoint for use with Datastax Langflow
  • Loading branch information
jordanrfrazier committed Oct 23, 2024
1 parent 6886ecb commit e0c3ce8
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 25 deletions.
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"]

0 comments on commit e0c3ce8

Please sign in to comment.