Dify: a self-hosted LLMOps platform
Table of contents
- Key takeaways
- What has changed since 1.15.0
- What is Dify?
- Deploying it with Docker Compose
- Apps: chat, agent and workflow
- RAG and knowledge base
- Dify versus Flowise and Langflow
- Frequently asked questions
- Is Dify really open source and free?
- Do I need to know how to code to use Dify?
- Can I use Dify with local models instead of the OpenAI API?
- Conclusion
- Sources
Tested with Dify 1.17.1 · Weaviate 1.39.2 · PostgreSQL 15 · Docker Compose 2.40 · verified
Updated: 2026-09-16
Dify is an open-source platform for building AI applications and agents, with a visual workflow canvas, prompt management, a RAG knowledge base and LLMOps layers. You can self-host the whole thing with Docker Compose on top of Postgres, Redis and a vector database. This guide explains how to deploy it and when it beats Flowise and Langflow.
Dify is an open-source platform that gathers into a single interface everything you need to build production AI applications. It includes a visual canvas to design workflows, prompt management, a knowledge base with RAG and the LLMOps layers to watch every run. The best part is that you can self-host the whole thing with Docker Compose, so neither your prompts nor your users’ data ever leave your server.
In this guide you will see what Dify is, how to deploy version 1.17.1 without leaving ports open and which app types it builds. You will also see how its RAG works and when it beats Flowise and Langflow. The same explanation is available in Spanish.
Key takeaways
- Dify is an open-source platform for developing AI applications and agents; on 16 September 2026 it had 155,981 stars and 1,473 contributors on GitHub, and the latest stable release is 1.17.1, from 10 September 2026.
- It is self-hostable: a single
docker compose up -dbrings up 16 services and, with the stock.env, publishes ports 80, 443 and 5003 on every network interface, so bind them to127.0.0.1before you start it. - It builds four app types with no code: chatbot, agent (with Function Calling and ReAct over more than 50 tools), a visual workflow and a text generator. Since 1.16.0 it adds Dify Agent, a beta agent that works inside a Linux sandbox.
- Its knowledge base bundles a full RAG pipeline: you upload PDF, PPT or Markdown, Dify chunks them, indexes them in a vector database and connects them to your apps with metadata filtering.
- Its licence is a modified version of Apache 2.0: you may use and sell it, but you cannot offer it as a multi-tenant service or remove the Dify logo from the console without a commercial agreement.
What has changed since 1.15.0
This guide was written against Dify 1.15.0 (25 June 2026). The current version is 1.17.1, released on 10 September 2026, with 1.16.0, 1.16.1 and 1.17.0 in between. Checked on 16 September 2026 against the repository’s release notes and with a fresh 1.17.1 install:
- Weaviate 1.39.2: 1.17.1[1] moves the bundled Weaviate up from 1.27.0 and pulls it from
cr.weaviate.io. If it already holds vectors, do not pull and restart. The notes require stepping through every minor version in order with the Weaviate server upgrade path[2], because skipping them can break vector search without warning. Fresh installs are unaffected. - Dify Agent (beta): 1.16.0, from 17 July 2026[3], introduced an agent that runs in a Linux sandbox, with its own builder, Skills and files, usable as a node inside a workflow or published as a web app. The team itself warns it should only be offered to trusted users.
- OpenAI plugin: since 1.16.0 new configurations use the Responses API instead of Chat Completions. If you saved a key with the old setting, review it before blaming Dify for errors with recent models.
- E2B sandbox, snapshots and Skill management: 1.17.0[4] lets the agent run on E2B sandboxes (
DIFY_AGENT_RUNTIME_BACKEND, with a newdocker-compose.e2b.yaml), captures the agent’s home directory when it is published so every run starts from the same state, and adds a workspace-level Skills manager with a draft, publish and version lifecycle. - LLM environment variables in workflows: 1.17.0 lets you define a provider, model and parameter configuration once and reference it from any LLM node, so a model change happens in one place and survives DSL export.
- Human input inside loops and iterations, opt-in unified tracing (
OPS_TRACE_UNIFIED_ENABLED, with Phoenix and LangSmith adapters), Cloudflare Turnstile on sign-in and a pluggable KMS with Azure Key Vault, all in 1.17.0. - Knowledge-base-scoped API keys: 1.17.1 lets you bind a service API key to specific knowledge bases, and the keys you already had keep working across the whole workspace. It also cuts how long each agent run’s events are kept from 3 days to 2 hours (
DIFY_AGENT_RUN_RETENTION_SECONDS).
The commands in this guide now pin 1.17.1. One note on the comparison at the end: the Flowise repository was archived read-only on 13 August 2026, so it is no longer an option for starting anything new.
What is Dify?
Dify is an open-source platform for building applications on top of language models, from a simple chatbot to an agent with tool access or a multi-step workflow. Its documentation calls it "an open-source platform for building AI applications" where you create agents, agentic workflows and chatbots that draw on your own data. It gathers into one product what you would normally assemble from half a dozen separate libraries, namely orchestration, prompt management, model connectivity, RAG and observability.
The project started in 2023 from LangGenius and has become one of the most popular AI repositories on GitHub. On 16 September 2026 it held 155,981 stars and 1,473 contributors, and its last four stable releases shipped between 11 and 28 days apart.
The underlying idea is that of an LLMOps platform. It is not enough for your application to work once on your laptop: you also want to review production logs, compare versions of a prompt and tune the model with real data. Dify puts those pieces within reach of a team that does not want to reinvent the plumbing.
Let us pin down the term in the title. LLMOps is to the lifecycle of language-model applications what DevOps is to traditional software: it covers design, deployment, monitoring and continuous improvement. Dify is not just a visual editor, it is that operational layer that logs every call, its cost and its latency, and lets you annotate responses to improve the system by iterating with evidence.
Deploying it with Docker Compose
Dify’s big advantage over a cloud service is that you can run it entirely on your own machine. Its documentation asks for 2 CPU cores, 4 GiB of RAM and Docker Compose 2.24.0 or later; on macOS, give the Docker Desktop virtual machine at least 8 GiB. If you do not have Docker yet, install it on Debian first. These commands download 1.17.1 and prepare the configuration:
git clone --depth 1 --branch 1.17.1 \
https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
The --branch 1.17.1 flag pins the stable release instead of the main branch, and --depth 1 downloads only that snapshot. Before you start anything, close the ports. With the stock .env, the nginx container publishes 80 and 443, and plugin_daemon publishes 5003 for remote plugin debugging, all three on every network interface.
The EXPOSE_* variables in .env set the host port, and the nginx ones also accept an IP. These are the values from our test; swap the ports for your own:
EXPOSE_NGINX_PORT=127.0.0.1:22280
EXPOSE_NGINX_SSL_PORT=127.0.0.1:22243
EXPOSE_PLUGIN_DEBUGGING_PORT=22203
TRIGGER_URL=http://localhost:22280
ENDPOINT_URL_TEMPLATE=http://localhost:22280/e/{hook_id}
NEXT_PUBLIC_SOCKET_URL=ws://localhost:22280
The last three lines add the port to the addresses Dify builds from a bare localhost. Those are the webhook trigger URLs, the plugin endpoint URLs and the WebSocket for collaborative editing. If you will reach Dify from another machine, put the public host name there instead of localhost.
The plugin debugging port does not accept an IP. Compose also passes EXPOSE_PLUGIN_DEBUGGING_PORT to the api container as PLUGIN_REMOTE_INSTALL_PORT, which only takes a number. With 127.0.0.1:22203, the 1.17.1 api configuration fails to load with the error PLUGIN_REMOTE_INSTALL_PORT must be a bare port number.
The fix that same error suggests is a docker-compose.override.yaml next to docker-compose.yaml, which Compose reads without being told. The !override tag replaces the port list instead of adding another entry to it, and it requires Docker Compose 2.24.4 or later[5], slightly above Dify’s minimum:
services:
plugin_daemon:
ports: !override
- "127.0.0.1:22203:5003"
With the ports closed, start the stack and check each service’s status:
docker compose up -d
docker compose ps -a --format 'table {{.Service}}\t{{.Status}}'
This is the output from the test. The uptimes differ because some services were recreated when the .env changed:
SERVICE STATUS
agent_backend Up About a minute
agent_ssrf_proxy Up 13 minutes
api Up About a minute (healthy)
api_websocket Up About a minute
db_postgres Up 13 minutes (healthy)
init_permissions Exited (0) About a minute ago
local_sandbox Up 13 minutes (healthy)
nginx Up 13 minutes
plugin_daemon Up About a minute
redis Up 3 minutes (healthy)
sandbox Up About a minute (healthy)
ssrf_proxy Up 13 minutes
weaviate Up 13 minutes
web Up About a minute
worker Up About a minute
worker_beat Up About a minute
That is 16 services, the same ones the Docker Compose deployment guide[6] lists. The seven core services start with the Python api and its api_websocket variant, which serves collaborative editing. Next come the Celery worker that processes queued tasks, the worker_beat that schedules them, the Next.js web, plugin_daemon and the Dify Agent agent_backend.
The eight dependencies are Postgres 15 for data, Redis 6 for the cache and the Celery task queue, Weaviate 1.39.2 as the vector database and nginx in front of everything. Two Squid proxies against server-side request forgery (SSRF), ssrf_proxy and agent_ssrf_proxy, and two sandboxes complete the list: one for workflow code and the agent’s local_sandbox. Service number 16, init_permissions, sets the storage permissions and exits with code 0.
If you prefer another vector database, swap Weaviate for Qdrant, Milvus or pgvector through the VECTOR_STORE variable in .env. With the images already pulled, the API was answering 26 s after up -d, on an 18-core arm64 machine shared with other jobs (load average between 2.3 and 4.7). At idle, with one empty app and no plugins, the 15 running containers added up to 2.0 GiB of RAM according to docker stats.
Open http://localhost:22280/install to create the admin account; from there, http://localhost:22280 takes you to the dashboard. Do it as soon as the stack is up. Until that admin exists, the install route asks for no credentials, and anyone who can reach the port can claim the account unless you set INIT_PASSWORD in .env.
Before exposing it to the internet, review these .env variables:
SECRET_KEY: leave it empty and Dify generates a persistent one in its storage, or set your ownDB_PASSWORDandREDIS_PASSWORD: both ship with the generic valuedifyai123456CELERY_BROKER_URL: repeats the Redis password inside the URL. If you change onlyREDIS_PASSWORD,docker compose psstill shows the services asUp, but theworkerlogsCannot connect to redis://:**@redis:6379/1: invalid username-password pair or user is disabled.in a loop.DIFY_AGENT_API_TOKENandDIFY_AGENT_SERVER_SECRET_KEY: the Dify Agent documentation[7] asks you to replace them with random values in productionDO_NOT_TRACK=true: it is not in.env.example. Add it and theworkerstops sendingotel.dify.aian anonymous heartbeat with the instance ID, version, operating system and architecture.
Finally, terminate HTTPS in front of the bundled nginx container, for example with Traefik, Caddy or Let’s Encrypt certificates. To upgrade, the 1.17.1 notes give this order. In a clone made with --depth 1, the git fetch line below replaces their git fetch --tags:
docker compose down
git fetch --depth 1 origin tag 1.17.1
git checkout 1.17.1
docker compose pull
docker compose up -d
We tested the two git commands by moving a 1.17.0 clone to 1.17.1. The Docker part with existing data was not tested in this review. If you use the bundled Weaviate and it already holds vectors, complete its upgrade path first.
Remember its licence, a modified version of Apache 2.0. Internal and commercial use is allowed, but you cannot offer Dify as a multi-tenant service or remove its logo from the console without written authorisation.
Apps: chat, agent and workflow
Once inside, Dify organises everything around four app types you pick when you create one. The chatbot is the most direct: you choose a model, write the system instructions and, optionally, attach a knowledge base to it. The text generator is its single-turn cousin, ideal for tasks like summarising or translating from a template with variables.
The two interesting types for anyone building agents are the agent and the workflow. The agent follows the classic reason-and-act pattern: you give it a goal and a set of tools, such as web search, a page reader or your own API through OpenAPI. The model decides at each iteration what to call, with Function Calling or ReAct strategies. Dify ships more than fifty built-in tools out of the box.
The workflow, in contrast, is a visual canvas where you chain nodes with full control over the path. Those nodes are model calls, conditions, loops, Python code or a human-input node that pauses execution to ask for approval. It is something like what LangGraph offers but without writing the graph by hand. That same canvas also has a variant built for the turn-by-turn flow of a conversation, called Chatflow, with its own memory and per-conversation variables.
The new Dify Agent, in beta since 1.16.0, has its own Agents page, and the documentation now calls the older type the Legacy Agent. It works in a sandbox of its own where it runs commands, installs programs and reads and writes files, and you use it as a chat app or as a step inside a workflow. Docker Compose turns it on by default, with its runtime in the agent_backend and local_sandbox services. To connect it to a model running on your machine, follow the guide on Dify Agent with a local model.
Any of those apps is published instantly as a REST API: Dify acts as the backend for your product, so your application only has to call an endpoint. This is how you talk to an already-published chatbot:
curl -X POST 'http://localhost:22280/v1/chat-messages' \
-H 'Authorization: Bearer app-your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {},
"query": "Summarise what an LLMOps platform is",
"response_mode": "streaming",
"user": "user-1"
}'
With a freshly created chatbot and a valid key, that call returned {"code":"invalid_param","message":"Provider openai does not exist.","status":400}. The route and the key work, but a new install ships with no model provider: install your provider’s plugin first from the Integrations menu. On the test machine we could not download packages from the Marketplace, so this review does not verify the model’s answer.
RAG and knowledge base
This is where Dify saves the most work. Building a RAG by hand means chunking documents, computing embeddings, choosing a vector database, writing the retrieval logic and stitching it all into the prompt. Dify packages that circuit in its knowledge base: you upload your files (PDF, Word, PPT, Markdown or a URL), choose how to chunk them and the platform handles the rest, vectorisation and indexing included.
At query time, Dify retrieves the most relevant chunks and injects them into the model’s context. You can tune the retrieval finely: choose between vector, keyword or hybrid search, or turn on a reranking model. And, since version 1.1.0, filter by metadata so a query only looks at certain documents.
Version 1.12.0 added the summary index: it generates a summary per chunk, not per whole document. When a query matches that summary, it retrieves every related chunk at once, which speeds up search over large volumes without losing context.
Because the answering model can be any of them, nothing stops you from serving one on your own machine with Ollama, through its OpenAI-compatible API. That gives you a full RAG where no data leaves your network.
Dify versus Flowise and Langflow
Dify is not alone: Flowise and Langflow compete on the same self-hostable visual-builder ground. The difference lies in each one’s philosophy.
| Platform | Focus | Licence | Minimum RAM | Strength |
|---|---|---|---|---|
| Dify | Full platform | Modified Apache 2.0 | 4 GiB | RAG, workspaces and LLMOps ready |
| Flowise | Node builder | MIT | No official figure | Archived on 13 August 2026 |
| Langflow | Visual builder in Python | MIT | 2 GB | Editable Python components |
Flowise and Langflow build on LangChain underneath and ask for fewer resources. Flowise used to start with npx flowise start, but its repository no longer receives changes. Langflow stands out when you need custom Python nodes, because it lets you edit the code of any component, and its documentation sets the minimum at 2 GB of RAM. Dify weighs more and asks for 4 GiB.
In exchange, it ships out of the box what the others lack. That is a mature knowledge base, workspaces with roles and permissions, a debugger that shows the time and tokens of each node, and the whole LLMOps layer.
A rule of thumb: start with Langflow to validate an idea fast, and migrate to Dify when you need serious RAG, team-based access control or production reliability. Flowise no longer belongs in that rule: its maintainers archived the repository on 13 August 2026 and wound the project down.
Frequently asked questions
Is Dify really open source and free?
Yes, with a caveat. The whole product is open source and you can self-host it at no cost, but its licence is not the standard Apache 2.0, rather a modified version with two conditions. The first stops you from offering Dify as a multi-tenant service to third parties without a commercial agreement; the second forbids removing the logo and copyright notices from the console. For a company’s internal use, for your own products or for learning, there is no practical limitation.
Do I need to know how to code to use Dify?
Not for the basics: you can build a chatbot with RAG, an agent with tools or a multi-step workflow with the visual interface, without writing a line of code. Coding helps you at two moments. The first is when you add a Python code node inside a workflow to transform data; the second, when you integrate the published apps into your product through the REST API. In that sense it is a low-code tool, not a no-code one.
Can I use Dify with local models instead of the OpenAI API?
Yes. Dify is agnostic about the model provider: you install whichever provider you want as a plugin, including the ones that serve models on your own machine, such as Ollama or any OpenAI-compatible server. By combining self-hosted Dify with a locally served model you get a complete AI platform in which no prompt or document leaves your network, which is decisive in environments with strict privacy requirements.
Conclusion
Dify solves the jump between "I have an idea for an AI app" and "I have an AI app in production that I can monitor and improve". With a docker compose up -d you bring up a complete platform. It builds chatbots, agents and visual workflows, integrates a RAG over your own knowledge base and logs every run with its cost. All within your network, and with 1,473 contributors behind it.
The next step is to clone version 1.17.1, bind its ports to 127.0.0.1 and bring up the containers. Then install a model provider and create your first chatbot app connected to a couple of documents to see the RAG in action.
Sources
- 1.17.1
- Weaviate server upgrade path
- 1.16.0, from 17 July 2026
- 1.17.0
- requires Docker Compose 2.24.4 or later
- Docker Compose deployment guide
- Dify Agent documentation
- Official Dify documentation
- Dify on GitHub
- Dify blog with the release notes
- Independent comparison of Dify, Flowise and Langflow
- Langflow installation requirements
- Archived Flowise repository
Source code
Access all the source code for this post on GitHub.
View on GitHub