# Stateless Langflow flow runtime (LFX). Serves versioned flow JSON files # deployed by our backend via POST /flows/upload/ (persisted in /flows). # LFX stays on the internal compose network; our FastAPI is the only # public surface and proxies run/stream calls. FROM python:3.12-slim ENV PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 # lfx = flow runtime; requests = convenience for custom-component code. # Pinned to the Langflow minor (contract: major.minor must match Langflow; # patches independent). Bump together with LANGFLOW_VERSION (.env.example). ARG LFX_VERSION=1.12.0 RUN pip install "lfx~=${LFX_VERSION}" requests # Non-root runtime: uploads persist into the mounted volume. The user needs # a home directory: lfx resolves settings/cache paths from $HOME, and # without one every flow run fails ("Settings service not found"). # gosu drops privileges in the entrypoint after chowning /flows: the named # volume arrives root-owned and the server user could otherwise never write # uploads (every deploy would fail with "Permission denied"). ENV HOME=/home/lfx RUN apt-get update \ && apt-get install -y --no-install-recommends gosu \ && rm -rf /var/lib/apt/lists/* \ && useradd -r -m -s /bin/false lfx && mkdir -p /flows && chown lfx /flows COPY lfx-entrypoint.sh /usr/local/bin/lfx-entrypoint.sh VOLUME /flows EXPOSE 6004 ENTRYPOINT ["sh", "/usr/local/bin/lfx-entrypoint.sh"] # Serve the /flows dir (uploaded flows persist there via --flow-dir). # No positional path: with one, lfx>=1.12.1 exits when the dir holds no # .json yet ("No .json files found"), restart-looping the container on # first boot. --flow-dir alone starts clean (health 200); the API sync # deploys backend/flows/*.json right after boot. # Flags verified against `lfx serve --help` (lfx 1.12.x). CMD ["lfx", "serve", "--host", "0.0.0.0", "--port", "6004", "--flow-dir", "/flows"]