Dify 可以做什么
聊天助手
文本生成应用
Agent
Chatflow 对话流:复杂流程的多轮对话场景,支持记忆,动态应用编排;
workflow 工作流:自动化、批处理等单轮生成类型任务的应用编排方式,单向生成结果;
下载安装 1 2 3 4 5 6 7 cd /home/cys/data/docker-datagit https://github.com/langgenius/dify.git cd /home/cys/data/docker-data/dify/dockerdocker compose up -d
修改配置 1 2 3 4 5 6 cd /home/cys/data/docker-data/dify/docker
存储位置 从你的 docker-compose.yml
文件可以看出,当前数据存储主要通过以下服务挂载到容器中:
PostgreSQL(db服务) :./volumes/db/data
Redis :./volumes/redis/data
Weaviate/Qdrant/Chroma等向量库 :./volumes/weaviate
、./volumes/qdrant
插件和存储目录 :./volumes/app/storage
其他辅助服务 :如 sandbox
、plugin_daemon
等
而我的dify 下载的位置本身就在 /home/cys/data/docker-data/dify
,/home/cys/data
下挂了52T的raid 磁盘空间是足够的。所以就不需要再修改了。
可以看见 数据其实都在 /home/cys/data/docker-data/dify/docker/volumes
中。
核心服务列表
服务名称
功能说明
端口映射/内部端口
nginx
反向代理,对外暴露 Web 和 API 服务
80:80
、443:443
web
Dify 前端界面
通过 nginx 代理(默认 80)
api
Dify 后端 API
通过 nginx 代理(默认 80)
worker
异步任务处理服务(如数据集处理、模型调用)
无直接暴露
db
PostgreSQL 数据库
内部 5432
redis
Redis 缓存
内部 6379
sandbox
代码沙箱环境(用于插件安全执行)
内部 8194
ssrf_proxy
安全代理服务(防止 SSRF 攻击)
内部 3128
plugin_daemon
插件守护进程(用于插件管理)
外部 5003:5003
weaviate
向量数据库(需手动启用)
内部 8080
qdrant
向量数据库(需手动启用)
内部 6333
elasticsearch
全文搜索服务(需手动启用)
外部 9200:9200
修改端口 1 2 3 4 5 6 sudo netstat -tuln | grep -E '8003|8004'
Docker-compose.yaml 的services:中,修改nginx服务的映射端口:
${EXPOSE_NGINX_PORT:-8003}:${NGINX_PORT:-8003}
'${EXPOSE_NGINX_SSL_PORT:-8004}:${NGINX_SSL_PORT:-8004}'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ------------------------------------------------------------------------ nginx: image: nginx:latest restart: always volumes: - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template - ./nginx/proxy.conf.template:/etc/nginx/proxy.conf.template - ./nginx/https.conf.template:/etc/nginx/https.conf.template - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/docker-entrypoint.sh:/docker-entrypoint-mount.sh - ./nginx/ssl:/etc/ssl - ./volumes/certbot/conf/live:/etc/letsencrypt/live - ./volumes/certbot/conf:/etc/letsencrypt - ./volumes/certbot/www:/var/www/html entrypoint: [ 'sh' , '-c' , "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ] environment: NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_} NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false} NGINX_SSL_PORT: ${NGINX_SSL_PORT:-8004} NGINX_PORT: ${NGINX_PORT:-8003} NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt} NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key} NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3} NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto} NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M} NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65} NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s} NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s} NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false} CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-} depends_on: - api - web ports: - '${EXPOSE_NGINX_PORT:-8003}:${NGINX_PORT:-8003}' - '${EXPOSE_NGINX_SSL_PORT:-8004}:${NGINX_SSL_PORT:-8004}' ------------------------------------------------------------------------
.env
1 2 3 4 5 EXPOSE_NGINX_PORT=8003 EXPOSE_NGINX_SSL_PORT=8004 NGINX_PORT=8003 NGINX_SSL_PORT=8004
防火墙给端口开一下;
1 2 sudo ufw allow 8003/tcp sudo ufw allow 8004/tcp
重启开启一下
1 2 docker compose down docker compose up -d
如果没有 成功开启 可以 docker compose logs nginx
检查一下 容器日志。
./nginx/docker-entrypoint.sh
这个脚本会决定最终生成的 default.conf
1 2 3 4 5 cys@cysserver:~/data/docker-data/dify/docker/nginx$ ls conf.d docker-entrypoint.sh https.conf.template nginx.conf.template proxy.conf.template ssl cys@cysserver:~/data/docker-data/dify/docker/nginx/conf.d$ ls default.conf default.conf.template default.conf~
我们可以看到 这个 default.conf
文件 中 监听的端口已经是8003了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server { listen 8003; server_name _; location /console/api { proxy_pass http://api:5001; include proxy.conf; } location /api { proxy_pass http://api:5001; include proxy.conf; } location /v1 { proxy_pass http://api:5001; include proxy.conf; } ... }
进入web页面 访问: http://10.5.9.252:8003/
注册一下Dify。
在设置中安装模型供应商的插件,我们之前在本地部署了 vllm集群的 Deepseek,也可以换大模型,但是换了模型就要在这里换一下对应的插件。
在这里可以 把我们之前本地部署的大模型和嵌入模型等等 都配置进去;
同样的道理,我之前在本地部署的 嵌入模型 也可以用同样的方法添加进来,在模型供应商中找啊到 我用的Text Embedding Inference。
我这里的 URL 是 http://10.5.9.252:8002
没有 带 /v1 。
插件中可见 已经有了 嵌入模型了。
AI 应用的创建 点击“工作室” 创建空白应用。
创建聊天助手
填写提示词
推荐用 大语言模型生成提示词,等个几十秒吧。
生成以后再应用一下就好。
在调试和预览、对话、知识库什么的都可以用,右上角可以换大模型。
创建Agent 打个比方 是 生成 图片的 Agent ,可以先本地运行一个 多模态的模型,然后 在插件中 下载一个 stability,在 工作室 Agent 界面下方 工具中添加 stability 插件。
创建文本生成应用
打一个 {
就会让你选择是否新建变量。
可见 右边 “调试与预览” 中 出现了左边 提示词的 内容;
点击运行
AI应用工具箱
以聊天助手为例
对话开场白 可以手动给用户选择,下一步问题的建议、 实现内容审查等等。
工作流(关键)
变量
系统变量(sys.xxx)、环境变量、会话变量 其实都是和编程语言类似的逻辑。
节点
chatflow工作流 我新建了一个 chatflow工作流(和workflow区别就是chatflow是对话形式)
选择直接回复大模型的text。
一个节点的输出喂下一个节点。
workflow工作流 workflow类似我原来开发的自动化处理流程,而chatflow类似于对话的形式;
一个是工作软件一个对对话助手。
知识库 RAG 可视化界面操作。
一个文件大小上限15M,
这里来设置如何切文档或者表格、文件的嵌入模型和检索设置;向量、全文还是混合搜索,之前的文档中我有过介绍。这样直接可视化的切分确实比open webUI看起来直观很多。
这样就添加好了一个 文件。
关联上知识库以后,就可以用了。
发布AI应用 由于我们是内网使用,所以直接运行在服务器上就可以了。
点击运行,会直接出现一个网址,别的机器访问这个url就可以实现访问dify。
或者点击下方的嵌入到网页,把一段它给出的 代码 粘贴进 html 的前端页面中即可。
或者 直接用 APIs ,不关注后端情况,直接用接口。
这样的做法可以让应用更加定制化一些,相比于open webUI。
动态更新 对于 docker compose 的 yaml 部署的 dify ,仅仅需要更新这三个容器就可以实现版本更新,但是注意好备份。注意步骤:
1、备份 PostgreSQL
2、备份你的挂载目录
3、备份配置文件.env 和yaml
4、修改docker-compose.yaml文件
5、拉取镜像,并重新启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 docker exec -t docker-db-1 pg_dump -U postgres dify > ./backup/dify_backup_$(date +%F).sql tar czf backup_volumes_$(date +%F).tar.gz ./volumes/app ./volumes/db ./volumes/redis cp .env backup/.env.bak_$(date +%F)cp docker-compose.yml backup/docker-compose.yml.bak_$(date +%F)services: api: image: langgenius/dify-api:latest web: image: langgenius/dify-web:latest worker: image: langgenius/dify-api:latest docker-compose pull docker-compose up -d
在docker ps 中可以看见 dify 版本。
遇到的问题以及解决方法 1、发布的时候,会出现404分不到,在“探索”中打开却能正常访问。 这是因为我前面yaml配置中env配置中修改过端口号。手动在生成的URL中的IP后添加端口即可。
同样的道理,在 **嵌入到前端页面 **中的时候也要加上端口号。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script > window .difyChatbotConfig = { token : 'RtixHB3eI1lQvUsR' , baseUrl : 'http://10.5.9.252' , systemVariables : { }, } </script > <script src ="http://10.5.9.252/embed.min.js" id ="RtixHB3eI1lQvUsR" defer > </script > <style > #dify-chatbot-bubble-button { background-color : #1C64F2 !important ; } #dify-chatbot-bubble-window { width : 24rem !important ; height : 40rem !important ; } </style >
上方统一需要在252后加 8003 我前面改的端口号。
2、Failed to parse response from plugin daemon to PluginDaemonBasicResponse 遇到报错:
Failed to parse response from plugin daemon to PluginDaemonBasicResponse [PluginListResponse], url: plugin/a7060300-e4d0-426c-8690-5036fef955e7/management/list
分析问题,是一个守护进程不停的访问,然后返回的格式又不匹配导致的。以下是分析过程: 我们先通过 日志确定问题 docker logs -f docker-plugin_daemon-1
,发现
2025/08/12 13:02:09 stdio.go:160: [INFO]plugin langgenius/huggingface_tei:0.0.3: Installed model: huggingface_tei 2025/08/12 13:02:09 stdio.go:160: [INFO]plugin langgenius/azure_openai:0.0.17: Installed model: azure_openai [GIN] 2025/08/12 - 13:02:23 | 200 | 19.930974ms | 172.20.0.8 | GET “/plugin/a7060300-e4d0-426c-8690-5036fef955e7/management/list?page=1&page_size=100”
而我通过 docker network ls
找到 3efdfbe91ed7 docker_default
;
docker network inspect dify_default
发现 前面日志中的 172.20.0.8 就是 docker-api-1。我们进一步看它的日志。
docker logs -f docker-api-1
提示说 返回的格式不匹配:
File “/app/api/.venv/lib/python3.12/site-packages/pydantic/main.py”, line 253, in init validated_self = self.pydantic_validator .validate_python(data, self_instance=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pydantic_core._pydantic_core.ValidationError: 1 validation error for PluginDaemonBasicResponse[PluginListResponse] data Input should be a valid dictionary or instance of PluginListResponse [type=model_type, input_value=[{‘id’: ‘f45acc46-9e4d-4f…5c71c2231’, ‘meta’: {}}], input_type=list] For further information visit https://errors.pydantic.dev/2.11/v/model_type
我确定了是之前的 插件或者插件容器相关的内容导致的问题,
解决思路如下:
1、清理 PostgreSQL + Redis 中的内容;
2、清理 本地残留插件文件;
3、进入 docker-compose.yaml 文件查看是否版本有明显偏差;
步骤:
1、清理 PostgreSQL + Redis 中的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker exec -it docker-db-1 psql -U postgres -l docker exec -it docker-db-1 psql -U postgres -d dify_plugin \dt select * from tool_installations; delete from tool_installations where tenant_id='a7060300-e4d0-426c-8690-5036fef955e7' ; exit docker exec -it docker-redis-1 redis-cli FLUSHALL exit
但是一个一个删除很慢,用下面的脚本 模糊搜索 删除也行;
vim clean_plugin.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #!/bin/bash set -ePLUGIN_ID="$1 " if [ -z "$PLUGIN_ID " ]; then echo "❌ 用法: $0 <插件ID或关键字>" exit 1 fi PG_CONTAINER="docker-db-1" REDIS_CONTAINER="docker-redis-1" echo "🔍 开始在 PostgreSQL 中搜索包含 [$PLUGIN_ID ] 的记录..." PG_MATCHES=$(docker exec -i "$PG_CONTAINER " psql -U postgres -d dify -t -A -c " SELECT table_name, column_name FROM information_schema.columns WHERE table_schema='public'; " | while IFS="|" read -r table column; do docker exec -i "$PG_CONTAINER " psql -U postgres -d dify -t -A -c \ "SELECT '$table ', '$column ', $column FROM \"$table \" WHERE CAST($column AS TEXT) LIKE '%$PLUGIN_ID %'" \ 2>/dev/null done )if [ -n "$PG_MATCHES " ]; then echo "找到以下匹配记录:" echo "$PG_MATCHES " else echo "✅ PostgreSQL 未找到匹配记录。" fi read -p "⚠️ 是否删除这些 PostgreSQL 记录?(y/n) " confirmif [[ "$confirm " == "y" ]]; then docker exec -i "$PG_CONTAINER " psql -U postgres -d dify -t -A -c " SELECT table_name, column_name FROM information_schema.columns WHERE table_schema='public'; " | while IFS="|" read -r table column; do docker exec -i "$PG_CONTAINER " psql -U postgres -d dify -c \ "DELETE FROM \"$table \" WHERE CAST($column AS TEXT) LIKE '%$PLUGIN_ID %'" \ 2>/dev/null || true done echo "🗑 PostgreSQL 相关记录已删除。" fi echo "🔍 开始在 Redis 中搜索包含 [$PLUGIN_ID ] 的键和值..." REDIS_KEYS=$(docker exec -i "$REDIS_CONTAINER " redis-cli --scan | grep "$PLUGIN_ID " || true ) REDIS_VAL_KEYS=$(docker exec -i "$REDIS_CONTAINER " redis-cli --scan | while read -r key; do if docker exec -i "$REDIS_CONTAINER " redis-cli GET "$key " 2>/dev/null | grep -q "$PLUGIN_ID " ; then echo "$key " fi done )if [ -n "$REDIS_KEYS$REDIS_VAL_KEYS " ]; then echo "找到以下 Redis 相关键:" echo "$REDIS_KEYS " echo "$REDIS_VAL_KEYS " else echo "✅ Redis 未找到匹配记录。" fi read -p "⚠️ 是否删除这些 Redis 键?(y/n) " confirmif [[ "$confirm " == "y" ]]; then echo "$REDIS_KEYS " "$REDIS_VAL_KEYS " | tr ' ' '\n' | sort -u | while read -r key; do docker exec -i "$REDIS_CONTAINER " redis-cli DEL "$key " >/dev/null done echo "🗑 Redis 相关键已删除。" fi echo "🎯 清理完成。"
运行上面脚本
1 2 3 chmod +x clean_plugin.sh./clean_plugin.sh a7060300-e4d0-426c-8690-5036fef955e7
2、清理 本地残留插件文件:
/home/cys/data/docker-data/dify/docker/volumes
是我的本地位置,如果你的目录结构不同,请替换路径。
1 2 3 4 5 cd /home/cys/data/docker-data/dify/docker/volumes/plugin_daemon/plugincd /home/cys/data/docker-data/dify/docker/volumes/plugin_daemon/plugin_packages
3、进入 docker-compose.yaml 文件修改;
1 2 3 4 docker-compose stop plugin_daemon docker-compose rm -f plugin_daemon docker rmi <plugin_daemon_image_name>
查看 GitHub中 项目的 docker-compose.yaml
中的 plugin_daemon
:
进入我们的 docker-compose.yaml
中修改 plugin_daemon
:,然后重新拉取,我这里是把 langgenius/dify-plugin-daemon:latest:0.0.9-local
改成 langgenius/dify-plugin-daemon:0.2.0-local
。
1 2 3 4 5 6 7 8 vim docker-compose.yaml docker-compose up -d plugin_daemon docker images | grep langgenius/dify-plugin-daemon
问题解决了。
参考: https://docs.dify.ai/zh-hans/guides/workflow/node/doc-extractor