Deploy Langflow on Docker
Podman can be used instead of Docker for all commands shown here. For more information, see the Podman documentation.
Running applications in Docker containers ensures consistent behavior across different systems and eliminates dependency conflicts.
Langflow publishes base, default, and extended application images with different provider inventories. Before deploying, see Choose a Langflow Docker image for the canonical tags, composition, version-pinning, migration, and rollback guidance.
This guide demonstrates several ways to run Langflow with Docker and Docker Compose:
- Quickstart: Start a Langflow container with default values.
- Use Docker Compose: Run Langflow with a persistent PostgreSQL database and configurable environment variables.
- Customize the Docker Compose file: Package a flow or add your own code into a custom image built on top of the official Langflow image.
- Build and run the Docker image from source: Build a Docker image from a local clone of the repo, or start a full development environment with hot reload on both frontend and backend.
- Upgrade the Langflow Docker image: Upgrade to a newer image without losing your database or flows.
- Docker image defaults: Environment variables included in the Langflow image and how to override them.
Quickstart
With Docker installed and running on your system, run the following command:
docker run -p 7860:7860 \
-e LANGFLOW_AUTO_LOGIN=false \
-e LANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORD \
langflowai/langflow:latest
Replace SUPERUSER_PASSWORD with a strong password for the Langflow superuser.
Official release packages, tagged source archives, and Docker images disable automatic login by default.
For a new Python package installation, do the following:
- Create a
.envfile with the following values:
LANGFLOW_AUTO_LOGIN=false
LANGFLOW_SUPERUSER_PASSWORD=REPLACE_WITH_A_STRONG_PASSWORD
- Start Langflow with the
.envfile:
uv run langflow run --env-file .env
- Sign in with the username
langflowor your configuredLANGFLOW_SUPERUSER.
For more information, see LANGFLOW_AUTO_LOGIN.
Then, access Langflow at http://localhost:7860/.
This starts a pre-built Docker image that requires users to sign in. For more control over the configuration, see Use Docker Compose.
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_exampledirectory:cd langflow/docker_example -
Set
LANGFLOW_SUPERUSER_PASSWORDin a.envfile in thedocker_exampledirectory. The Compose file requires this value because official images disable automatic login.echo 'LANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORD' > .envReplace
SUPERUSER_PASSWORDwith a strong password for the Langflow superuser.noteOfficial release packages, tagged source archives, and Docker images disable automatic login by default.
For a new Python package installation, do the following:
- Create a
.envfile with the following values:
LANGFLOW_AUTO_LOGIN=falseLANGFLOW_SUPERUSER_PASSWORD=REPLACE_WITH_A_STRONG_PASSWORD- Start Langflow with the
.envfile:
uv run langflow run --env-file .env- Sign in with the username
langflowor your configuredLANGFLOW_SUPERUSER.
For more information, see
LANGFLOW_AUTO_LOGIN. - Create a
-
Run the Docker Compose file:
docker compose up -
Access Langflow at
http://localhost:7860/.
Customize the Docker Compose file
Customize the Docker Compose file to fit your deployment's requirements.
Include environment variables
Configure a container's database credentials using a .env file.
-
Create a
.envfile with your database credentials in the same directory asdocker-compose.yml:# Database credentialsPOSTGRES_USER=myuserPOSTGRES_PASSWORD=mypasswordPOSTGRES_DB=langflow# Langflow configurationLANGFLOW_DATABASE_URL=postgresql://myuser:mypassword@postgres:5432/langflowLANGFLOW_CONFIG_DIR=/app/langflowLANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORDReplace
SUPERUSER_PASSWORDwith a strong password for the Langflow superuser. -
Edit
docker-compose.ymlto replace the hardcoded values with variable references for both thelangflowandpostgresservices: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
.envfile at startup.
For a complete list of available environment variables, see Langflow environment variables.
Package a flow into the image
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 flowwget https://raw.githubusercontent.com/langflow-ai/langflow-helm-charts/refs/heads/main/examples/flows/basic-prompting-hello-world.json# Or copy your own flow filecp /path/to/your/flow.json . -
Create a
Dockerfile:FROM langflowai/langflow:latestRUN mkdir /app/flowsCOPY ./*.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.0docker push myuser/langflow-custom:1.0.0 # optional
For Kubernetes deployment, see Deploy the Langflow production environment on Kubernetes.
Add custom code or dependencies
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.pyfile in that directory. -
Create a
Dockerfile:FROM langflowai/langflow:latestWORKDIR /appCOPY src/lfx/src/lfx/components/models_and_agents/memory.py /tmp/memory.pyRUN python -c "import site; print(site.getsitepackages()[0])" > /tmp/site_packages.txtRUN 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 7860CMD ["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
Build and run the Docker image from source
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:
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 \
-e LANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORD \
langflow:VERSION
Replace the following:
SUPERUSER_PASSWORD: a strong password for the Langflow superuserVERSION: the version inpyproject.tomlat the repo root
The image sets LANGFLOW_AUTO_LOGIN=false, so a superuser password is required unless you set LANGFLOW_AUTO_LOGIN=true.
For more information, see Docker image defaults.
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.
Write a custom source-based Dockerfile
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.lockCOPY ./README.md /app/README.mdCOPY ./pyproject.toml /app/pyproject.tomlCOPY ./src/backend/base/README.md /app/src/backend/base/README.mdCOPY ./src/backend/base/pyproject.toml /app/src/backend/base/pyproject.tomlCOPY ./src/lfx/README.md /app/src/lfx/README.mdCOPY ./src/lfx/pyproject.toml /app/src/lfx/pyproject.tomlCOPY ./src/sdk/README.md /app/src/sdk/README.mdCOPY ./src/sdk/pyproject.toml /app/src/sdk/pyproject.tomlCOPY ./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 devCOPY ./src /app/srcRUN --mount=type=cache,target=/root/.cache/uv \uv sync --frozen --no-editable --extra postgresql --no-group devThe first
uv syncinstalls only dependencies before the source is copied, so that Docker can cache that layer. The seconduv syncinstalls 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.
The supported source build uses
docker/build_and_push.Dockerfile.
Build its base target for the bundle-free application, full for the normal
curated distribution, or full-bundles for the extended provider inventory.
Start a development environment with make dcdev_up
make 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_AUTO_LOGIN | false | Require users to sign in unless explicitly enabled for local development |
LANGFLOW_CONFIG_DIR | /var/lib/langflow | Directory for Langflow config and data |
Set LANGFLOW_SUPERUSER_PASSWORD to a strong password in the repository root .env file before startup. The service loads this file through env_file: ../.env; it does not override the authentication values in its environment: block. Set LANGFLOW_SUPERUSER in that file to use a different username. For trusted local development, set LANGFLOW_AUTO_LOGIN=true in the same file to use automatic login instead. When omitted, auto-login retains the image default of false. The legacy password langflow is not allowed when auto-login is disabled.
Exporting these authentication variables in your shell alone does not forward them to this service; configure them in the repository root .env file.
LANGFLOW_DATABASE_URL and LANGFLOW_CONFIG_DIR remain literal values in the Compose environment: block to configure the bundled PostgreSQL service and container paths. These entries take precedence over .env; edit docker/dev.docker-compose.yml directly to change them.
Upgrade the Langflow Docker image
If your existing instance uses auto-login, prepare the existing account for password sign-in before switching to an image that requires authentication. Setting LANGFLOW_SUPERUSER_PASSWORD alone does not reset an existing account's non-legacy password.
Unless you set LANGFLOW_DATABASE_URL or LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true, Langflow stores its SQLite database inside the container, not on a mounted volume.
Unless you set LANGFLOW_CONFIG_DIR to the mounted path, Langflow also stores its secret key and uploaded files inside the container.
Removing or recreating that container deletes this data, even if a volume is mounted.
If your current container was started without these settings, move its data to a volume before you upgrade.
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. Mount a Docker volume or bind mount at the path in
LANGFLOW_CONFIG_DIR, and keep the database outside of the container. To use PostgreSQL, setLANGFLOW_DATABASE_URL. To keep SQLite, setLANGFLOW_SAVE_DB_IN_CONFIG_DIR=true, which stores the database in the config directory. For example, this Docker Compose file uses a bind mount for Langflow data (./langflow-dataon the host) and a named volume for the PostgreSQL database (langflow-postgres):services:langflow:image: langflowai/langflow:1.13.0ports:- "7860:7860"depends_on:- postgresenvironment:- LANGFLOW_DATABASE_URL=postgresql://langflow:langflow@postgres:5432/langflow- LANGFLOW_CONFIG_DIR=/app/langflow- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}volumes:- ./langflow-data:/app/langflowpostgres:# 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/9608image: postgres:16-trixieenvironment:POSTGRES_USER: langflowPOSTGRES_PASSWORD: langflowPOSTGRES_DB: langflowvolumes:- langflow-postgres:/var/lib/postgresql/datavolumes:langflow-postgres:On Linux, if
./langflow-datadoesn't exist, Docker creates it owned byroot, and Langflow fails to start with aPermissionError. Before you start Langflow, create the directory next to the Compose file, and make the Langflow user (UID1000) its owner:mkdir -p langflow-datasudo chown -R 1000:0 langflow-dataFor 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.ymlordocker runcommand.With Docker Compose, set the image in your compose file, such as
image: langflowai/langflow:1.13.0, and then pull:docker compose pullWith
docker run, pull the image:docker pull langflowai/langflow:1.13.0 -
Restart the container. The same volumes will be reattached, so your database and flows are preserved.
With Docker Compose:
docker compose up -dWith
docker run, stop and remove the old container, and then start a new container with the same volume mount and the new image tag:docker run -p 7860:7860 \-v langflow-data:/app/langflow \-e LANGFLOW_CONFIG_DIR=/app/langflow \-e LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true \-e LANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORD \langflowai/langflow:1.13.0Replace
SUPERUSER_PASSWORDwith a strong password for the Langflow superuser. This command stores the SQLite database, secret key, and uploaded files in thelangflow-datavolume. To use PostgreSQL instead, replaceLANGFLOW_SAVE_DB_IN_CONFIG_DIR=truewithLANGFLOW_DATABASE_URL.
This approach keeps the persistent volumes separate from the Langflow container, so you can upgrade the Langflow application without losing data.
Move data from a container to a volume
If your current container was started without LANGFLOW_DATABASE_URL or LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true, its SQLite database is inside the container.
If it was also started without LANGFLOW_CONFIG_DIR, its secret key and uploaded files are inside the container too.
Without the original secret key, Langflow can't decrypt saved credentials, such as Credential global variables.
To keep this data, copy it to a volume before you remove the container:
-
While the container is running, list the data files that are stored inside it:
docker exec OLD_CONTAINER sh -c 'find / -xdev \( -name "langflow*.db" -o -name secret_key \) 2>/dev/null'Replace
OLD_CONTAINERwith the name or ID of the container. To find it, rundocker ps. The output lists the paths to copy. The paths depend on the image version. For example:/app/data/.cache/langflow/secret_key/app/.venv/lib/python3.14/site-packages/langflow/langflow.dbIf the output is empty, the container already stores its data on a volume or in an external database.
-
Stop the container, so SQLite writes all pending changes to the database file:
docker stop -t 60 OLD_CONTAINERThe
-t 60option gives Langflow up to 60 seconds to shut down before Docker kills it. -
Copy the config directory, which is the directory that contains
secret_key, and the database file to a backup directory on the host. Use the paths from step 1:mkdir langflow-backupdocker cp OLD_CONTAINER:/app/data/.cache/langflow/. langflow-backup/docker cp OLD_CONTAINER:/app/.venv/lib/python3.14/site-packages/langflow/langflow.db langflow-backup/If step 1 listed only the database file, skip the first
docker cpcommand. The backup contains your secret key, so keep it private.Then copy the
langflow.db-walandlangflow.db-shmfiles from the same directory as the database file. These files exist only if Langflow didn't shut down cleanly, and they can hold changes that aren't inlangflow.dbyet:docker cp OLD_CONTAINER:/app/.venv/lib/python3.14/site-packages/langflow/langflow.db-wal langflow-backup/docker cp OLD_CONTAINER:/app/.venv/lib/python3.14/site-packages/langflow/langflow.db-shm langflow-backup/If Docker reports
Could not find the file, the database file already holds all changes. -
Copy the backup into the volume, and make the Langflow user (UID
1000) the owner of the files:docker run --rm --user root \-v langflow-data:/app/langflow \-v "$PWD/langflow-backup:/backup:ro" \langflowai/langflow:1.13.0 \sh -c 'cp -R /backup/. /app/langflow/ && chown -R 1000:0 /app/langflow'Replace
langflow-datawith your volume name, or with the host path of your bind mount, such as"$PWD/langflow-data". Docker Compose adds the project name to volume names. To find the name, rundocker volume ls. With Docker Desktop, create the backup directory in a location that Docker can share, such as your home directory. -
Start the new container with
LANGFLOW_CONFIG_DIR=/app/langflowandLANGFLOW_SAVE_DB_IN_CONFIG_DIR=true, as shown in thedocker runcommand in the upgrade steps. With Docker Compose, addLANGFLOW_SAVE_DB_IN_CONFIG_DIR=trueto theenvironmentlist. Don't pointLANGFLOW_DATABASE_URLat a new PostgreSQL database for this data. That database starts empty, because Langflow doesn't copy SQLite data into it. -
Sign in, and confirm that your flows, API keys, and files are present. Then remove the old container:
docker rm OLD_CONTAINER
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").
Docker image defaults
Official release packages, tagged source archives, and Docker images disable automatic login by default.
For a new Python package installation, do the following:
- Create a
.envfile with the following values:
LANGFLOW_AUTO_LOGIN=false
LANGFLOW_SUPERUSER_PASSWORD=REPLACE_WITH_A_STRONG_PASSWORD
- Start Langflow with the
.envfile:
uv run langflow run --env-file .env
- Sign in with the username
langflowor your configuredLANGFLOW_SUPERUSER.
For more information, see LANGFLOW_AUTO_LOGIN.
As of Langflow 1.11.x, official Langflow Docker images set LANGFLOW_AUTO_LOGIN=false at image build time.
DEV and CDK images set LANGFLOW_AUTO_LOGIN=false starting in Langflow 1.13.
To enable automatic login in a container, set LANGFLOW_AUTO_LOGIN=true:
docker run -p 7860:7860 \
-e LANGFLOW_AUTO_LOGIN=true \
-e LANGFLOW_SUPERUSER_PASSWORD=SUPERUSER_PASSWORD \
langflowai/langflow:latest
For more information, see Component hardening for untrusted users and Block custom components.
Was this page helpful?