Why host LangFlow on a VPS
LangFlow addresses a specific use case: designing AI pipelines by dragging and dropping components — LLM models, retrievers, prompts, memory, agents — then testing them without writing a single line of code. It is the visual alternative to code-only LangChain, suited to teams that want to iterate quickly before committing logic to Python.
On a VPS, you get a stable and persistent instance accessible to the whole team, unlike a local setup that disappears on reboot. Your flows often encode sensitive business logic — prompt chains, API keys, connectors to your databases. This data should not pass through a SaaS whose data retention policy you do not control.
LangFlow relies on FastAPI on the server side and exposes each flow as a REST endpoint: your applications can call your AI pipelines directly, with no intermediary code. It is this combination — visual interface for design, API for integration — that makes it a serious prototyping tool for use cases such as document RAG, support chatbots, multi-step agents, or classification pipelines.
What you gain with a self-hosted instance
- Visual pipeline interface — drag LLM, retriever, memory, and prompt components onto a canvas, connect them, and test without code.
- Multiple LLM connectors — OpenAI, Anthropic, Ollama (local), Hugging Face, and any OpenAI-compatible provider.
- Built-in RAG — load PDF or text documents, with chunking, embedding and vector search in the same flow.
- Automatic API per flow — each pipeline becomes a REST endpoint callable from any application.
- Encrypted global variables — your API keys are stored server-side, never exposed in the client code.
- Custom Python components — extend LangFlow with your own business logic without forking the project.
- Flow version control — export as JSON and version in Git, independently of the database state.
Prerequisites before you start
LangFlow is more memory-intensive than a typical web application: its execution engine loads models and embeddings into RAM. Plan for at least 2 vCPU and 4 GB of RAM for comfortable use. If you connect a local Ollama model for inference on the same VPS, move to 8 GB minimum.
On the software side, you need Docker (version 24 or later) and Docker Compose v2, installed and running. Port 7860 must be accessible locally (LangFlow listens on this port by default). You do not expose this port directly to the internet: the nginx reverse proxy handles that.
Prepare a subdomain pointing to your VPS IP — for example langflow.your-domain.com — with DNS records already propagated before running certbot. Finally, a PostgreSQL database is strongly recommended for production: the default SQLite corrupts under concurrent load and does not support simultaneous access by multiple users.
Install LangFlow with Docker Compose and PostgreSQL
Create the working directory
Log in to your VPS via SSH, then create the folder that will host the stack:
mkdir -p /opt/langflow && cd /opt/langflowWrite the docker-compose.yml file
Create a
docker-compose.ymlfile with two services —postgresandlangflow— and authentication environment variables:services: postgres: image: postgres:16 restart: unless-stopped environment: POSTGRES_USER: langflow POSTGRES_PASSWORD: strong-password POSTGRES_DB: langflow volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U langflow"] interval: 10s retries: 5 langflow: image: langflowai/langflow:latest restart: unless-stopped ports: - "127.0.0.1:7860:7860" environment: LANGFLOW_DATABASE_URL: postgresql://langflow:strong-password@postgres:5432/langflow LANGFLOW_SECRET_KEY: change-this-to-a-random-string LANGFLOW_AUTO_LOGIN: "false" LANGFLOW_SUPERUSER: admin LANGFLOW_SUPERUSER_PASSWORD: strong-admin-password depends_on: postgres: condition: service_healthy volumes: pgdata:Note two important points: port
7860is bound to127.0.0.1(LangFlow is not reachable from the outside without going through the proxy), and thehealthcheckonpostgresensures LangFlow waits for a truly ready database before starting, avoiding silently failing first requests.Start the stack
Start both containers in the background:
docker compose up -dFollow LangFlow logs during the first initialization (schema creation in the database, roughly 30 seconds to 1 minute):
docker compose logs -f langflowWait for the line indicating that the server is listening on port
7860before continuing.Verify the interface responds
From your VPS, test that LangFlow responds locally before setting up the proxy:
curl -s http://127.0.0.1:7860/healthThe expected response is
{"status":"ok"}. If you get a connection refused error, the startup logs contain the cause.Configure the nginx reverse proxy with HTTPS
Install nginx and certbot if not already done, then create a configuration file:
server { listen 80; server_name langflow.your-domain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name langflow.your-domain.com; ssl_certificate /etc/letsencrypt/live/langflow.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/langflow.your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:7860; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }The
UpgradeandConnectionheaders are essential for WebSocket support, used by the interactive canvas. Obtain the certificate with certbot:certbot --nginx -d langflow.your-domain.comLog in and create your first flow
Open
https://langflow.your-domain.comin your browser. Log in with the credentials set inLANGFLOW_SUPERUSERandLANGFLOW_SUPERUSER_PASSWORD. In the interface, click New Flow, choose a template or start from an empty canvas. Add an LLM component, a prompt and an output component, connect them, then click Run to test the pipeline.Store API keys in global variables
Rather than entering your API keys in each component, use Global Variables (icon at the top right): the key is encrypted in the database and reusable across all your flows. From the API menu of a flow, you retrieve the
curlor Python call code to integrate this pipeline into an external application.Back up flows and the database
Schedule a daily
pg_dumpof the database from the host:docker exec langflow-postgres-1 pg_dump -U langflow langflow > /opt/backups/langflow-$(date +%F).sqlAlso export your flows as JSON from the Export menu of each flow: it is a versionable safety net in Git, independent of the database state.
Calling a flow from an application: REST API
Each LangFlow flow is accessible via the /api/v1/run/<flow-id> endpoint. You find the flow identifier in the editor URL or in the flow's API menu. Two concrete examples.
With curl:
curl -s -X POST \
https://langflow.your-domain.com/api/v1/run/YOUR-FLOW-ID \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR-API-KEY" \
-d '{
"input_value": "What is the capital of France?",
"input_type": "chat",
"output_type": "chat"
}'With Python (requests library):
import requests
FLOW_ID = "YOUR-FLOW-ID"
BASE_URL = "https://langflow.your-domain.com"
API_KEY = "YOUR-API-KEY"
response = requests.post(
f"{BASE_URL}/api/v1/run/{FLOW_ID}",
headers={
"Content-Type": "application/json",
"x-api-key": API_KEY,
},
json={
"input_value": "What is the capital of France?",
"input_type": "chat",
"output_type": "chat",
},
timeout=60,
)
result = response.json()
print(result["outputs"][0]["outputs"][0]["results"]["message"]["text"])The API key is generated in Settings → API Keys in the LangFlow interface. It authenticates each call and can be revoked at any time without touching the flow.
RAG pipeline: index your documents and query them
RAG (Retrieval-Augmented Generation) is the central use case of LangFlow: you load documents (PDF, text, Markdown), split them into chunks, embed them into a vector database, then an LLM answers questions by drawing on this context.
Which VectorStore on a VPS? On a server with limited resources, Chroma (ChromaDB) is the lightest choice: it runs in-process in the same LangFlow container, requires no additional service, and persists its data in a local directory. Qdrant is suitable if you have more RAM and want a dedicated service in a neighboring container.
Building the indexing pipeline in LangFlow:
In the editor, assemble the following chain by dragging components:
1. File (or Directory) → loads the PDF or document folder.
2. Split Text → splits into chunks (recommended size: 500 to 800 tokens, overlap 50).
3. OpenAI Embeddings (or Ollama Embeddings to stay fully local) → transforms each chunk into a vector.
4. Chroma DB → stores the vectors. Point the Persist Directory field to a Docker-mounted volume so the index survives restarts.
For the Chroma volume, add to your docker-compose.yml:
langflow:
volumes:
- chromadb:/data/chroma
volumes:
pgdata:
chromadb:Then define the LangFlow global variable CHROMA_PERSIST_DIR with the value /data/chroma.
Query pipeline:
Once the index is populated, create a second flow: Text Input → Chroma DB (in search mode, same directory) → Prompt (inject retrieved chunks) → LLM → Chat Output. Each question triggers a vector search, retrieves the closest passages, and submits them to the model with context.
Custom components: extending LangFlow in Python
LangFlow lets you create custom Python components without forking the project. A component is a class that inherits from Component and declares its inputs, outputs, and logic.
Minimal example — a component that cleans and uppercases received text:
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Data
class UpperCaseComponent(Component):
display_name = "Uppercase Text"
description = "Converts text to uppercase."
inputs = [
MessageTextInput(
name="input_text",
display_name="Input Text",
)
]
outputs = [
Output(
display_name="Processed Text",
name="output_text",
method="process_text",
)
]
def process_text(self) -> Data:
result = self.input_text.strip().upper()
return Data(text=result)To add this component to your instance: in the LangFlow interface, go to Settings → Custom Components, paste the code and save. The component immediately appears in the sidebar, ready to be dragged into any flow.
Updating LangFlow without losing your data
LangFlow releases updates regularly (the 1.x branch is the active stable branch as of October 2026). Before any update, systematically back up the database:
docker exec langflow-postgres-1 pg_dump -U langflow langflow \
> /opt/backups/langflow-before-update-$(date +%F).sqlThen update the image and restart the stack:
cd /opt/langflow
docker compose pull
docker compose up -dFollow the logs to detect any automatic schema migrations:
docker compose logs -f langflowWatch out for breaking changes in v1.x. Some components are renamed or refactored between minor versions. Export your flows as JSON before upgrading — it is the fastest way to restore them to a known state if a migration causes issues.
To pin a specific version (recommended in production), replace latest with the desired tag in your docker-compose.yml:
image: langflowai/langflow:1.12.4Advanced configuration: useful environment variables
LangFlow exposes several environment variables to adapt the instance to your context. LANGFLOW_SECRET_KEY encrypts sensitive data stored in the database — change the default value before first startup, as a later rotation invalidates existing encrypted data. LANGFLOW_AUTO_LOGIN set to false always requires an explicit login, even from localhost. LANGFLOW_WORKERS controls the number of Uvicorn processes: the default value (1) is suitable for moderate use, increase to 2 or 4 if multiple users execute flows simultaneously.
For flows that call local models via Ollama, define OLLAMA_BASE_URL in LangFlow's global variables rather than in the Docker environment: the value is then managed by the interface and can be changed without a restart.
If you update LangFlow, always do a pg_dump before docker compose pull && docker compose up -d: some version upgrades touch the database schema.
Security: do not expose LangFlow directly to the internet
LangFlow has no built-in rate limiting on its API endpoints. Without additional measures, a publicly exposed flow can be called without limit by anyone who knows the URL. Two approaches complement each other.
First, keep LANGFLOW_AUTO_LOGIN=false permanently and create distinct user accounts for each team member. Second, if your flows should only be called by your own applications (rather than by direct users), add an auth_basic nginx block in front of the management interface and expose only the /api/v1/run/<flow-id> endpoints with token authentication to your applications.
Never leave LangFlow in production with SQLite: the database corrupts under concurrent access and you lose your flows without an explicit error message.
Extended troubleshooting: common errors
OOM error (Out of Memory). If the LangFlow container restarts spontaneously, check docker compose logs langflow and look for Killed. The cause is insufficient RAM. Reduce LANGFLOW_WORKERS to 1 and, if the problem persists, increase the VPS RAM or avoid running heavy flows simultaneously.
RuntimeError: CUDA out of memory. This error occurs when a component attempts to use a GPU (via PyTorch or a Hugging Face model) but the VPS has none, or GPU memory is insufficient. Force CPU execution by adding the environment variable CUDA_VISIBLE_DEVICES="" to the langflow service in docker-compose.yml. If the error comes from a Hugging Face model, select a CPU variant (suffix -cpu or gguf) in the component.
Port 7860 already in use. If docker compose up -d fails with address already in use, another process is listening on that port. Identify it with ss -tlnp | grep 7860 and stop it, or change the host port in docker-compose.yml (for example "127.0.0.1:7861:7860") and update the nginx configuration accordingly.
ImportError: No module named 'torch' or missing dependency. Some advanced components (Hugging Face embeddings, local models) require heavy libraries not included in the base image. Create a derived Dockerfile that installs missing dependencies, or use the langflowai/langflow-backend image with the required extras.
Connection refused to Ollama. If LangFlow cannot reach Ollama running on the same VPS, check that Ollama listens on 0.0.0.0 and not only on 127.0.0.1. In docker-compose.yml, add extra_hosts: ["host-gateway:host-gateway"] to the LangFlow service and use the address http://host-gateway:11434 in LangFlow's Ollama components.
Blank canvas or disconnected WebSocket. Check that the Upgrade and Connection headers are properly forwarded by nginx. An intermediate proxy (Cloudflare in Full Strict mode, load balancer) may intercept WebSockets: ensure the WebSocket protocol is properly configured in the proxy.
Missing or incomplete flow logs. LangFlow stores execution logs in the database. If the PostgreSQL database was not ready when LangFlow started, the first requests fail silently. The healthcheck in the docker-compose.yml example above resolves this problem.
Next steps: extending your LangFlow instance
Once LangFlow is running, several integrations expand its scope.
If you want a fully local LLM model (without any external API call), install Ollama on the same VPS and connect it to LangFlow via the Ollama component: your pipelines no longer send data outside your infrastructure. Ollama exposes an OpenAI-compatible API on port 11434.
For more robust document RAG, move from Chroma to Qdrant — an open source vector database you deploy in a neighboring container with better performance on large corpora.
Finally, if multiple teams use the instance, consider isolating flows by workspace (feature available depending on the version) or deploying one LangFlow instance per project with the ServOrbit template, which automatically configures Docker Compose, PostgreSQL and the reverse proxy.