docs/docs/Deployment/deployment-docker.mdx
import PartialPodmanAlt from '@site/docs/_partial-podman-alt.mdx';
<PartialPodmanAlt />Running applications in Docker containers ensures consistent behavior across different systems and eliminates dependency conflicts.
This guide demonstrates several ways to run Langflow with Docker and Docker Compose:
With Docker installed and running on your system, run the following command:
docker run -p 7860:7860 -e LANGFLOW_AUTO_LOGIN=true langflowai/langflow:latest
Then, access Langflow at http://localhost:7860/.
This starts a pre-built Docker image with automatic login enabled for local development. For more control over the configuration, see Use Docker Compose.
Docker Compose gives you more control over your configuration, such as setting environment variables, using a persistent PostgreSQL database instead of the default SQLite database, and including custom dependencies.
The Langflow repo includes a ready-to-use Compose file at docker_example/docker-compose.yml that pulls the latest Langflow image from Docker Hub and includes persistent volume storage with PostgreSQL.
Clone the Langflow repository:
git clone https://github.com/langflow-ai/langflow.git
Navigate to the docker_example directory:
cd langflow/docker_example
Run the Docker Compose file:
docker compose up
Access Langflow at http://localhost:7860/.
Customize the Docker Compose file to fit your deployment's requirements.
Configure a container's database credentials using a .env file.
Create a .env file with your database credentials in the same directory as docker-compose.yml:
# Database credentials
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=langflow
# Langflow configuration
LANGFLOW_DATABASE_URL=postgresql://myuser:mypassword@postgres:5432/langflow
LANGFLOW_CONFIG_DIR=/app/langflow
LANGFLOW_SUPERUSER_PASSWORD=replace-with-a-strong-password
Edit docker-compose.yml to replace the hardcoded values with variable references for both the langflow and postgres services:
services:
langflow:
environment:
- LANGFLOW_DATABASE_URL=${LANGFLOW_DATABASE_URL}
- LANGFLOW_CONFIG_DIR=${LANGFLOW_CONFIG_DIR}
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
postgres:
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
With variable references in place, Docker Compose reads the values from your .env file at startup.
For a complete list of available environment variables, see Langflow environment variables.
Embed a flow JSON directly into a Docker image. This is useful for distributing a specific flow as a standalone container or deploying it to environments like Kubernetes.
Create a project directory and change into it:
mkdir langflow-custom && cd langflow-custom
Add your flow's JSON file to the directory. You can download an example, or use your own:
# Download an example flow
wget https://raw.githubusercontent.com/langflow-ai/langflow-helm-charts/refs/heads/main/examples/flows/basic-prompting-hello-world.json
# Or copy your own flow file
cp /path/to/your/flow.json .
Create a Dockerfile:
FROM langflowai/langflow:latest
RUN mkdir /app/flows
COPY ./*.json /app/flows/
ENV LANGFLOW_LOAD_FLOWS_PATH=/app/flows
Build, test, and optionally push your image:
docker build -t myuser/langflow-custom:1.0.0 .
docker run -p 7860:7860 -e LANGFLOW_AUTO_LOGIN=true myuser/langflow-custom:1.0.0
docker push myuser/langflow-custom:1.0.0 # optional
For Kubernetes deployment, see Deploy the Langflow production environment on Kubernetes.
Patch custom code into the pre-built image's installation. This is useful when you need to add custom Python packages, replace a built-in component, or make targeted changes without a full source build.
This example replaces the built-in Message History component, but the same pattern applies to any component or file.
Create a directory for your custom Langflow setup:
mkdir langflow-custom && cd langflow-custom
Create the directory structure that mirrors the component path:
mkdir -p src/lfx/src/lfx/components/models_and_agents
Place your modified memory.py file in that directory.
Create a Dockerfile:
FROM langflowai/langflow:latest
WORKDIR /app
COPY src/lfx/src/lfx/components/models_and_agents/memory.py /tmp/memory.py
RUN python -c "import site; print(site.getsitepackages()[0])" > /tmp/site_packages.txt
RUN SITE_PACKAGES=$(cat /tmp/site_packages.txt) && \
mkdir -p "$SITE_PACKAGES/lfx/components/models_and_agents" && \
cp /tmp/memory.py "$SITE_PACKAGES/lfx/components/models_and_agents/"
RUN SITE_PACKAGES=$(cat /tmp/site_packages.txt) && \
find "$SITE_PACKAGES" -name "*.pyc" -delete && \
find "$SITE_PACKAGES" -name "__pycache__" -type d -exec rm -rf {} +
EXPOSE 7860
CMD ["python", "-m", "langflow", "run", "--host", "0.0.0.0", "--port", "7860"]
Build and run the image:
docker build -t myuser/langflow-custom:1.0.0 .
docker run -p 7860:7860 -e LANGFLOW_AUTO_LOGIN=true myuser/langflow-custom:1.0.0
:::tip
Both make docker_build and make lfx_docker_build use Podman by default. If you have Docker installed instead, pass the alias DOCKER=docker on the command line:
make docker_build DOCKER=docker
:::
If you've cloned the Langflow repository and want to build and run your local changes inside a Docker container, run:
```shell
make docker_build
```
This builds docker/build_and_push.Dockerfile and tags the result langflow:<version>.
To run the image after building, run:
docker run -p 7860:7860 langflow:<version>
Replace <version> with the version in pyproject.toml at the repo root.
To build only the LFX executor CLI image instead of the full Langflow application, run:
make lfx_docker_build
This builds src/lfx/docker/Dockerfile and tags the result lfx:latest.
It produces a lightweight Alpine-based image that contains only the lfx CLI tool, with no frontend or Langflow UI.
The build context is the repo root, not src/lfx/. The Dockerfile copies from pyproject.toml, uv.lock, src/lfx/, and src/sdk/, so the full workspace is sent to the daemon. A root .dockerignore file partially mitigates this, but the first build will be slower than you might expect for a small CLI image.
When writing a source-based Dockerfile, you must copy the manifest files (pyproject.toml, README.md, and uv.lock where present) for the workspace members that uv sync needs to resolve dependencies before source is available.
The workspace members are defined in [tool.uv.workspace] in the root pyproject.toml.
You do not need to copy manifests for members like src/langflow-stepflow that are not required for the initial dependency-only sync.
The full source is copied later with COPY ./src, which brings those omitted members into the image before the second uv sync.
To copy all manifest files to your Dockerfile, include the following:
COPY ./uv.lock /app/uv.lock
COPY ./README.md /app/README.md
COPY ./pyproject.toml /app/pyproject.toml
COPY ./src/backend/base/README.md /app/src/backend/base/README.md
COPY ./src/backend/base/pyproject.toml /app/src/backend/base/pyproject.toml
COPY ./src/lfx/README.md /app/src/lfx/README.md
COPY ./src/lfx/pyproject.toml /app/src/lfx/pyproject.toml
COPY ./src/sdk/README.md /app/src/sdk/README.md
COPY ./src/sdk/pyproject.toml /app/src/sdk/pyproject.toml
COPY ./src/bundles /app/src/bundles
To install dependencies and copy the source, include the following:
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-editable --extra postgresql --no-group dev
COPY ./src /app/src
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-editable --extra postgresql --no-group dev
The first uv sync installs only dependencies before the source is copied, so that Docker can cache that layer. The second uv sync installs the project packages (langflow, lfx) from the copied source. Both calls are required. Omitting the second will produce a container with all dependencies present but the project packages missing, which fails at runtime.
For an example, see docker/build_and_push_with_extras.Dockerfile.
make dcdev_upmake dcdev_up starts a full development environment from source using docker/dev.docker-compose.yml.
This is useful if you want to work on the Langflow codebase within a container.
To build the Langflow dcdev image, run:
make dcdev_up
Access the backend and Langflow UI at http://localhost:7860/.
Access the frontend dev server at http://localhost:3000/.
The following environment variables are set by default:
| Variable | Default value | Description |
|---|---|---|
LANGFLOW_DATABASE_URL | postgresql://langflow:langflow@postgres:5432/langflow | PostgreSQL connection string |
LANGFLOW_SUPERUSER | langflow | Initial admin username |
LANGFLOW_SUPERUSER_PASSWORD | langflow | Initial admin password |
LANGFLOW_CONFIG_DIR | /var/lib/langflow | Directory for Langflow config and data |
To override these values, edit docker/dev.docker-compose.yml directly.
docker/dev.docker-compose.yml uses literal values in its environment: block, such as - LANGFLOW_SUPERUSER=langflow. Docker Compose v2 gives environment: block literal values higher precedence than shell-exported variables and env_file:, so neither export LANGFLOW_SUPERUSER=myadmin or a .env file will override them. Edit the file directly instead.
To upgrade a Langflow Docker deployment without losing your database or flows, do the following:
Keep data on persistent volumes, so when you upgrade Langflow, you will replace only the container image.
Use Docker volumes or bind mounts for Langflow data and the database so they persist outside of the container.
For example, this Docker Compose file uses a bind mount for Langflow data (./langflow-data on the host) and a named volume for the PostgreSQL database (langflow-postgres):
services:
langflow:
image: langflowai/langflow:1.11.0
environment:
- LANGFLOW_CONFIG_DIR=/app/langflow
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
volumes:
- ./langflow-data:/app/langflow
postgres:
# Pinned to a specific Debian base (trixie) so the postgres:16 tag does
# not silently roll its OS, which triggers a glibc collation mismatch
# warning on existing volumes. See https://github.com/langflow-ai/langflow/issues/9608
image: postgres:16-trixie
volumes:
- langflow-postgres:/var/lib/postgresql/data
volumes:
langflow-postgres:
For additional examples, see the Docker Compose configuration and the docker_example compose file.
Pull the new image and update the image tag in your docker-compose.yml or docker run command.
With Docker Compose, set the image in your compose file, such as image: langflowai/langflow:1.11.0, and then pull:
docker compose pull
With docker run, pull the image:
docker pull langflowai/langflow:1.11.0
Restart the container. The same volumes will be reattached, so your database and flows are preserved.
With Docker Compose:
docker compose up -d
With docker run, use the same volume mount and the new image tag:
docker run -p 7860:7860 -v langflow-data:/app/langflow -e LANGFLOW_SUPERUSER_PASSWORD=replace-with-a-strong-password langflowai/langflow:1.11.0
This approach keeps the persistent volumes separate from the Langflow container, so you can upgrade the Langflow application without losing data.
If you need to upgrade to a custom image based on a Langflow release, such as to add uv in 1.8.0, first build a derived image from the official image, and then follow the same steps above.
Set the custom image in your compose file or docker run, and then pull and restart.
For a minimal Dockerfile that adds uv to the 1.8.0 image, see the release notes ("Docker image no longer includes uv or uvx").