What Is Flowise and Why Self-Host It?
Flowise is an open-source, drag-and-drop LLM app builder. You connect nodes — language models, vector stores, document loaders, memory buffers, tools — into a chatflow or agentflow using a visual canvas. No glue code. No boilerplate. The finished flow gets an API endpoint automatically.
The cloud version works fine for prototyping. But the moment you're loading proprietary documents, storing conversation history, or routing customer traffic through it, you want your data on your own infrastructure. Self-hosting also means no per-message billing surprises and no vendor lock-in on the orchestration layer — you're only paying for the LLM API calls you make.
This guide gets you from zero to a production-ready Flowise instance: Docker Compose stack, persistent PostgreSQL database, HTTPS via Traefik, API key auth, and your first RAG pipeline running.
Prerequisites
You'll need:
- A Linux server (Ubuntu 22.04 / 24.04 recommended) with at least 2 vCPU and 2 GB RAM
- Docker Engine v24+ and Docker Compose v2 installed
- A domain name with a DNS A record pointing to your server's public IP
- Ports 80 and 443 open in your firewall
- An API key from at least one LLM provider (OpenAI, Anthropic, Groq, Ollama, etc.)
- Basic familiarity with the command line
# Quick environment check
docker --version # should be 24+
docker compose version # should be v2.x
# Confirm ports are free
sudo ss -tlnp | grep -E ':80|:443|:3000'
If you haven't set up a reverse proxy yet, our introductory Flowise self-host guide covers the basics of the visual canvas and core concepts before you dive into production setup.
Step 1: Directory Structure and Environment File
Keep everything in one place. You'll thank yourself during upgrades.
mkdir -p /opt/flowise
cd /opt/flowise
# Create the .env file — never commit this to version control
cat > .env <<'EOF'
# --- Flowise App ---
FLOWISE_USERNAME=admin
FLOWISE_PASSWORD=changeme_strong_password
FLOWISE_SECRETKEY_OVERWRITE=a_random_32char_secret_key_here
PORT=3000
# --- Database (PostgreSQL) ---
DATABASE_TYPE=postgres
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE_USER=flowise
DATABASE_PASSWORD=changeme_db_password
DATABASE_NAME=flowise
# --- Storage ---
BLOB_STORAGE_PATH=/root/.flowise/storage
# --- Postgres container ---
POSTGRES_USER=flowise
POSTGRES_PASSWORD=changeme_db_password
POSTGRES_DB=flowise
EOF
chmod 600 .env
A few notes on these variables:
FLOWISE_USERNAMEandFLOWISE_PASSWORDenable Flowise's built-in basic auth on the UI. Set these before first launch.FLOWISE_SECRETKEY_OVERWRITEis the key used to encrypt stored credentials (API keys you enter in the UI). Lose this and your stored keys are unreadable — back it up.- SQLite is the default database, but for anything beyond local testing, PostgreSQL gives you proper concurrent writes, backups, and replication.
Step 2: Docker Compose Stack with PostgreSQL
Here's the full docker-compose.yml. It runs Flowise and PostgreSQL together, both connected to the shared Traefik network for HTTPS routing.
# /opt/flowise/docker-compose.yml
services:
flowise:
image: flowiseai/flowise:latest
container_name: flowise
restart: unless-stopped
env_file: .env
volumes:
- flowise_data:/root/.flowise
depends_on:
postgres:
condition: service_healthy
labels:
- "traefik.enable=true"
- "traefik.http.routers.flowise.rule=Host(`flowise.yourdomain.com`)"
- "traefik.http.routers.flowise.entrypoints=websecure"
- "traefik.http.routers.flowise.tls=true"
- "traefik.http.routers.flowise.tls.certresolver=letsencrypt"
- "traefik.http.services.flowise.loadbalancer.server.port=3000"
networks:
- traefik-public
- flowise-internal
postgres:
image: postgres:16-alpine
container_name: flowise-postgres
restart: unless-stopped
env_file: .env
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U flowise"]
interval: 10s
timeout: 5s
retries: 5
networks:
- flowise-internal
volumes:
flowise_data:
postgres_data:
networks:
traefik-public:
external: true
flowise-internal:
internal: true
The flowise-internal network is marked internal: true, which means PostgreSQL has no route to the internet — only Flowise can reach it. The Traefik network is external and shared with other services on your server.
If you don't have Traefik running yet, set it up first — our full Flowise deployment walkthrough covers getting the stack online end to end.
Start the stack:
cd /opt/flowise
# Create the shared Traefik network if it doesn't exist yet
docker network create traefik-public 2>/dev/null || true
# Start the stack
docker compose up -d
# Watch startup logs
docker compose logs -f flowise
Within 30–60 seconds Flowise should be live at https://flowise.yourdomain.com. Log in with the username and password you set in .env.
Step 3: Build Your First RAG Chatflow
A RAG (Retrieval-Augmented Generation) chatflow is the most common starting point. You upload documents, chunk and embed them into a vector store, then wire a chat model to retrieve relevant chunks before generating a response. In Flowise, this is entirely visual.
The Node Pipeline
Open the Flowise UI, click Add New in the Chatflows section, then drag these nodes onto the canvas:
- PDF File Loader (or any Document Loader) — source of your content
- Recursive Character Text Splitter — splits documents into chunks
- OpenAI Embeddings (or any embedding model) — converts chunks to vectors
- In-Memory Vector Store (or Qdrant / Pinecone / Postgres pgvector) — stores embedded chunks
- ChatOpenAI (or any chat model) — the LLM that generates answers
- Conversational Retrieval QA Chain — the orchestrator that ties retrieval to generation
- Buffer Memory — maintains conversation history across turns
Connect them in order: Loader → Splitter → Embeddings → Vector Store → QA Chain ← Chat Model ← Buffer Memory.
Adding Your LLM API Key
Flowise stores provider credentials securely inside the UI — you don't put them in environment variables. On any LLM or Embeddings node, click the Connect Credential dropdown, then Create New to add your OpenAI, Anthropic, or other API key. Flowise encrypts it at rest using FLOWISE_SECRETKEY_OVERWRITE.
Test with the Built-in Chat Widget
Click Save on your chatflow, then hit the chat bubble icon in the top-right corner of the canvas. Upload a PDF and ask it a question. If retrieval is working, the answer will be grounded in your document content rather than hallucinated from training data.
Go deeper: Our Flowise assistants and document processing pipelines guide covers advanced Document Store setups, evaluation flows, and integrating Flowise with the rest of your stack.
Step 4: Expose Your Chatflow as an API
Every chatflow in Flowise gets a REST API endpoint automatically. This is how you embed the LLM capability into your own applications without rebuilding the pipeline.
Get the Chatflow ID
Open your chatflow and copy the ID from the URL bar: https://flowise.yourdomain.com/chatflow/your-chatflow-id.
Query the API
# Basic unauthenticated call (fine for internal services)
curl -X POST \
https://flowise.yourdomain.com/api/v1/prediction/your-chatflow-id \
-H "Content-Type: application/json" \
-d '{"question": "What does the document say about refund policies?"}'
Enable Chatflow-Level API Key Auth
For any externally accessible chatflow, lock it down with a per-chatflow API key:
- In the Flowise UI, go to API Keys in the left sidebar
- Click Create API Key, give it a name, copy the key
- Open your chatflow → Chatflow Configuration → assign the key
Now authenticated calls require the key in the header:
curl -X POST \
https://flowise.yourdomain.com/api/v1/prediction/your-chatflow-id \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-flowise-api-key" \
-d '{"question": "Summarize the Q3 earnings report."}'
Stream Responses
For chat UIs where you want token-by-token streaming, pass "streaming": true in the request body. Flowise returns a Server-Sent Events stream:
curl -X POST \
https://flowise.yourdomain.com/api/v1/prediction/your-chatflow-id \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-flowise-api-key" \
-H "Accept: text/event-stream" \
-d '{"question": "Explain this in simple terms.", "streaming": true}'
Step 5: Production Hardening
The default Docker setup is enough to get running. Here's what to add before you put real traffic on it.
Pin the Flowise Version
Never run flowiseai/flowise:latest in production. Pin to a specific version so you control when you upgrade:
# In docker-compose.yml, replace:
# image: flowiseai/flowise:latest
# with a specific tag, e.g.:
# image: flowiseai/flowise:2.2.7
# Check available versions on Docker Hub
docker pull flowiseai/flowise --list-digests 2>/dev/null || \
echo "Browse: https://hub.docker.com/r/flowiseai/flowise/tags"
Back Up PostgreSQL
# Manual dump
docker exec flowise-postgres pg_dump -U flowise flowise > \
/opt/flowise/backups/flowise-$(date +%Y%m%d-%H%M%S).sql
# Add to cron for daily automated backups (runs at 2am)
# crontab -e
# 0 2 * * * docker exec flowise-postgres pg_dump -U flowise flowise > \
# /opt/flowise/backups/flowise-$(date +\%Y\%m\%d).sql 2>&1
Resource Limits
Add resource constraints to prevent a runaway flow from taking down the whole server:
# Add to the flowise service in docker-compose.yml
deploy:
resources:
limits:
cpus: "2.0"
memory: 2G
reservations:
memory: 512M
Restrict CORS Origins
If your Flowise API is called from a specific frontend domain, lock down CORS to prevent abuse. Set this in your .env:
# .env additions
CORS_ORIGINS=https://app.yourdomain.com,https://dashboard.yourdomain.com
IFRAME_ORIGINS=https://app.yourdomain.com
Going further: For multi-tenant deployments, custom node development, and advanced RAG tuning, see our deep-dive on Flowise production RAG tuning, custom nodes, and API security.
Step 6: Troubleshooting and Common Gotchas
Here's what actually breaks and how to fix it.
UI Login Loop / 401 After Setting Credentials
Symptom: You set FLOWISE_USERNAME and FLOWISE_PASSWORD but the browser keeps bouncing back to the login page.
- Make sure both variables are set — Flowise only enables auth when both are present. One without the other disables the login screen entirely.
- After changing credentials, clear your browser's cookies/localStorage for the Flowise domain — stale session tokens cause infinite redirects.
- Restart the container after any
.envchange:docker compose down && docker compose up -d
Stored API Keys Showing as Encrypted Garbage After Restart
Symptom: LLM nodes say "Invalid API Key" after a container restart even though the key was saved.
This happens when FLOWISE_SECRETKEY_OVERWRITE changes between restarts. Flowise uses this key to encrypt stored credentials — if it changes, existing encrypted values can't be decrypted. Fix: restore the original secret key value in your .env, or re-enter your credentials in the UI after setting a stable key.
Chatflow Returns 404 on the API Endpoint
- Verify the chatflow is saved and not in draft state.
- Double-check the chatflow ID in the URL — copy it directly from the Flowise UI, not from memory.
- If you migrated from SQLite to PostgreSQL, flows may need to be re-imported. Export them as JSON from the old instance under Chatflows → Export, then import on the new one.
PostgreSQL Connection Refused at Startup
Symptom: Flowise logs show ECONNREFUSED connecting to PostgreSQL immediately after stack start.
This is a startup race condition. The healthcheck + depends_on: condition: service_healthy in the Compose file above solves it — Flowise waits until PostgreSQL passes its pg_isready check before starting. If you see this on an older Compose config, add the healthcheck block shown in Step 2.
Memory / OOM Kills on Large Document Ingestion
Embedding large PDFs in one shot can spike memory hard. Fix options:
- Use the Document Store feature (chunked background upsert) instead of inline loaders in the chatflow
- Reduce chunk size in the Text Splitter node (try 500–800 characters with 50–100 overlap)
- Increase container memory limits or server RAM
Check Logs for Any Issue
# Flowise application logs
docker compose logs -f flowise
# PostgreSQL logs
docker compose logs -f postgres
# Filter for errors only
docker compose logs flowise 2>&1 | grep -i "error\|warn\|fatal\|refused"
What to Build Next
Once your instance is running, here's where most teams go next:
- Agentflows — swap the QA Chain for an Agent node, add tools (web search, SQL query, custom HTTP calls), and Flowise handles the ReAct loop automatically
- Document Store — manage your vector embeddings outside individual chatflows; update one store and every chatflow using it picks up the changes
- Flowise Assistants — OpenAI-style persistent assistants with file attachments, code interpreter, and thread management, all visual
- Embedded chat widget — one script tag drops a fully functional chat UI into any webpage, backed by your self-hosted chatflow
- Webhook triggers — connect Flowise flows to external events from Zapier, Make, or your own services via the Prediction API
The combination of a visual builder, an instant REST API, and full self-hosting is what makes Flowise worth running over cobbling together LangChain scripts manually. Your flows are portable, debuggable through the UI, and version-controllable as JSON exports.
Need a Production-Ready LLM Stack for Your Team?
Standing up a personal Flowise instance is one afternoon. Building a multi-tenant, monitored, secured, and scalable LLM platform that your whole company runs on is a different project entirely.
If you're deploying LLM infrastructure for a team or product and want it done right the first time, reach out to Sysbrix. We design and run production AI infrastructure — from self-hosted model serving to full RAG pipelines — so your team can focus on the applications, not the plumbing.