简介Dify 官方安装包是从 GitHub 获取的项目主体压缩包面向希望本地部署、源码研读或二次开发 AI 应用编排平台的开发者适合用于搭建开发测试环境、了解项目模块组织以及扩展功能。压缩包共 2000 个文件整体约 20.25MB其中 Python 源码 1337 个构成后端逻辑的主要部分JSON 配置 366 个CSS 与 JavaScript 文件合计 200 个承担前端样式与交互资源另有 Markdown 文档、YAML 部署配置、Shell 脚本及少量 HTML、XML、SQL 等覆盖配置说明、界面呈现和基础数据等层面。已有 2982 人学习下载具备一定参考热度。解压后可获得较完整的项目主体便于查看前后端资源分布、理解模块职责与部署配置关系也能为本地运行、功能改造和源码分析提供基础材料。对于需要核对官方目录结构、梳理依赖关系或进行二次开发的人而言这份主体包能减少收集零散文件的时间也便于对照模块边界开展调试与扩展。1. Dify 官方安装包一次up -d卡在向量库上的教训第一次在自己机器上起 Dify我照着官方 compose 一路docker compose up -d前端页面一直转圈api容器日志里反复刷weaviate:8080 connection refused。查了半小时才发现新版的 compose 文件把向量库放进了 profiles不带--profile启动根本不会拉起那个容器。这类坑跟功能一点关系都没有全在环境里。Dify 官方安装包的价值也在这儿它把 api、worker、web、PostgreSQL、Redis、向量库、沙箱这十来个容器编排成一份 compose镜像、网络、依赖顺序都写好了。需要对齐的只有版本、端口、密钥三样。这篇笔记写给两种人第一次在自己服务器上装 Dify 的和装到一半卡住、想找出哪里不对的。下面按装前、装中、装坏、装完验证的顺序走。2. 装前环境清单Docker Engine 与 Compose v2 的版本取舍Dify 的部署形态是「一个 compose 文件带一组容器」没有任何需要编译的步骤所以环境准备的重点不是语言运行时而是容器运行时本身。这一步选错了版本后面全是白费功夫用 Compose v1 的docker-compose去跑带profiles的编排文件会出现某些服务被静默跳过的情况报错信息还特别含糊。2.1 宿主机要什么规格CPU、内存、磁盘的底线官方给的最低配置是 2 核 4GB这个数字能跑起来但只限于「跑起来」——一旦开始建知识库、做文档分段索引内存立刻见底。我的经验是项目能跑的下限我建议的配置说明CPU2 核4 核文档解析、向量化是 CPU 密集型内存4 GB8 GB 起api worker 向量库 PostgreSQL 同时在线磁盘20 GB50 GB 以上镜像本身占十几个 G知识库文件另算系统主流 Linux 发行版x86_64 或 arm64 均可注意镜像架构要和宿主机一致磁盘容易被低估。Dify 全部镜像拉下来光api和web两个就上 G加上向量库、PostgreSQL、沙箱20G 的云盘很快就满然后你在某次docker compose pull时收到磁盘不足的报错。我一般会把/var/lib/docker单独挂一块盘或者至少提前确认根分区有 30G 余量。提示如果是 4GB 内存的机器硬上先把 swap 开出来fallocate -l 4G /swapfile那一套能避免 worker 被 OOM killer 直接干掉。但 swap 只是应急用长期跑还是加内存。2.2 装 Docker Engine 与 Compose v2一条不重复调整的安装步骤Dify 要求 Compose v2也就是docker compose中间是空格这个插件形态不是老的docker-compose中间是横杠。两条命令长得像但后者在新编排文件上会出问题这是我最常见的翻车点之一。以 Debian/Ubuntu 系为例先清掉发行版源里自带的老包避免和官方包打架# 1) 卸载系统自带的老版本 docker避免与官方仓库的包冲突 sudo apt-get remove -y docker docker-engine docker.io containerd runc # 2) 安装基础依赖为添加官方软件源做准备 sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings # 3) 添加 Docker 官方软件源具体源地址与 keyring 路径以官方安装文档为准 # 这一步照着文档逐行粘即可注意 keyring 不要放到 /etc/apt/trusted.gpg.d # ... # 4) 安装引擎 compose 插件 buildx sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin # 5) 当前用户加入 docker 组之后不用每条命令都 sudo需重新登录生效 sudo usermod -aG docker $USER第 4 步里的docker-compose-plugin是关键装的就是 v2 版 Compose提供docker compose子命令。第 5 步加组是为了省事但要注意加组之后重新登录一次否则docker ps还是 permission denied很多人在这一步以为是安装失败其实只是 shell 没刷新。装完立刻验证别等部署时才发现版本不对# 引擎版本关注 Server 那一段是否有输出 docker version --format {{.Server.Version}} # Compose 版本必须是 v2.x输出形如 Docker Compose version v2.x.x docker compose version # 确认没有残留的 v1 老命令 which docker-compose如果docker compose version报的是docker: compose is not a docker command说明插件没装上回到第 4 步检查包名。如果which docker-compose有输出说明机器上还躺着 v1 版本建议直接apt-get remove docker-compose卸掉防止后面手滑敲错。启用服务并设置开机自启服务器重启后容器能自己回来sudo systemctl enable --now docker # 容器级别也要在 compose 里带 restart: always官方文件默认就有2.3 端口与目录80、5001、3000 该由哪个服务对外暴露Dify 的 compose 里对外暴露的只有 nginx 一个入口默认 80HTTP和 443HTTPS。内部的api走 5001、web走 3000这些端口不需要也不应该直接暴露到公网。这个层级关系搞清楚后面端口冲突时才知道改谁。端口谁在用是否需要对外冲突时怎么改80nginx 容器是改.env里的EXPOSE_NGINX_PORT443nginx 容器是用 HTTPS 时改EXPOSE_NGINX_SSL_PORT5001api 容器否不要动只在内网3000web 容器否不要动只在内网5432PostgreSQL否不要动6379Redis否不要动装之前先看一眼宿主机 80 端口有没有人占着这一步能省你半小时# 看 80 和 443 是否被占用有输出说明已经有服务在监听 sudo ss -lntp | grep -E :80|:443云服务器上很常见的情况是预装了 nginx 或 apache 当默认站点占了 80。这时候有两个选择停掉宿主机的 web 服务或者把 Dify 的对外端口改成 8080。我更倾向后者因为宿主机的 nginx 可能还挂着别的站点。改法在.env里把EXPOSE_NGINX_PORT设成 8080后面访问就带端口。目录规划同理提前想好。Dify 的 compose 会把持久化数据落到docker/volumes/下面部分版本用命名卷整个项目目录我一般放在/opt/dify这种位置而不是某个用户的家目录——家目录权限和磁盘配额都可能成为以后的问题。3. 拿官方安装包仓库拉取到 .env 逐项改完安装包拿法只有一条正路从官方仓库拉取对应稳定 tag 的源码用里面的docker目录。第三方打包的「一键脚本」我见过几个改过端口、加过默认密钥、版本还落后出了问题没法排查不建议用。3.1 拉取官方发布包与 docker 目录结构说明仓库地址从官方发布页复制不要凭记忆敲。拉下来之后切到一个明确的稳定 tag别用主分支——主分支的 compose 文件随时会动你昨天跑通的步骤今天可能就变了# 从官方发布页复制仓库地址拉取完整仓库 git clone 官方仓库地址 dify cd dify # 切到发布页上标注的稳定 tag比主分支可控得多 git checkout 稳定版 tag # 确认目录结构后面所有操作都在 docker 目录里进行 ls -la docker/docker/目录里最关键的三个东西docker-compose.yaml编排定义、.env.example环境变量模板、nginx/反向代理配置。.env不存在需要你自己从模板复制。这里有个细节值得说如果你不想用 git官方发布页上也提供源码压缩包下载解压效果一样只是后续升级时要重新下载。用 git 的好处是升级时git pull加git checkout新 tag 就行改动痕迹也好追溯。3.2 .env.example 复制成 .env 后必须改的六个参数这一步是整个安装里最需要人盯的地方。复制很容易改对不容易。cd docker cp .env.example .env # 生成一个随机 SECRET_KEY不要用模板里的默认值 openssl rand -base64 42把生成结果填进.env的SECRET_KEY。然后逐项对照参数模板默认值我一般改成作用与影响SECRET_KEY示例字符串openssl rand -base64 42的输出会话和令牌签名不换等于把钥匙插门上DB_PASSWORD默认弱密码强密码PostgreSQL 密码改了要保证 api 能读到REDIS_PASSWORD默认弱密码强密码Redis 认证VECTOR_STOREweaviateweaviate或qdrant向量库类型改了要同步改 profilesEXPOSE_NGINX_PORT8080 或 8080对外 HTTP 端口FILES_URL空http://你的IP或域名文件预览、下载的根地址FILES_URL是最容易被跳过的一项。不填也能启动上传文件也能成功但点开预览时链接指向容器内部地址浏览器打不开。同域部署填对外访问地址即可如果你前面还有一层反向代理填代理后的完整地址。还有几个参数默认留空只在分离部署时才需要填CONSOLE_API_URL、CONSOLE_WEB_URL、SERVICE_API_URL、APP_WEB_URL。单机 compose 部署全部留空就行填了反而容易出跨域问题。CODE_EXECUTION_ENDPOINT默认指向http://sandbox:8194这是容器间通信用服务名不要改成 IP除非你把沙箱拆出去单独部署了。注意.env里出现密码这类敏感信息改完把权限收紧chmod 600 .env。整个目录如果是多人共用这一条别省。3.3 向量库选型与 profilesVECTOR_STORE 怎么改才不返工Dify 支持多种向量库compose 文件里通过 profiles 控制哪个服务被拉起。.env里的VECTOR_STORE和 compose 里的服务名必须对上对不上就是我最开始那个坑api 起来了向量库没起日志一直重连。先确认你的 compose 文件用的是哪种机制# 列出当前 compose 文件里所有服务不带 profile 时只会列默认服务 docker compose config --services # 看 weaviate 或 qdrant 是否带了 profiles 标记 grep -A3 profiles docker-compose.yaml | head -20如果config --services的输出里没有 weaviate说明它被 profile 藏起来了启动时要显式带上# 显式指定 profile把向量库一起拉起来 docker compose --profile weaviate up -d # 如果选用 qdrant则换成对应的 profile 名 # docker compose --profile qdrant up -d选哪个单机小规模、图省事weaviate是默认值改都不用改。数据量上了百万级向量、想要更可控的内存占用可以换qdrant代价是要改VECTOR_STORE并带上对应 profile。不管选哪个改了向量库类型之后已建的知识库数据不会自动迁移这一点在建第一个知识库之前就要定下来别等有数据了再换。另外提醒一句compose 里的向量库服务通常没有对宿主机暴露端口只在容器网络内可达这是对的不要为了「方便调试」把它 expose 出去。4. 首次启动docker compose up -d 之后的三分钟配置改完剩下的动作很少但等待过程里要看的日志不少。首次启动的耗时基本都花在拉镜像上容器真正起来的顺序是秒级的。4.1 拉镜像与启动镜像体积大时的处理方式cd /opt/dify/docker # -d 后台启动--profile 与 .env 里的 VECTOR_STORE 保持一致 docker compose --profile weaviate up -d # 盯着拉取进度首次会比较久 docker compose ps首次拉取的总量不小api、web、向量库、沙箱加起来是几个 G 的量级具体取决于你选的向量库。国内机器上耗时可能到十几分钟甚至更久这段时间不用反复 CtrlC 重来中断反而会让已完成的分层白拉。我的习惯是先单独把大镜像拉下来# 先把体积大的几个拉完再整体 up失败重试的成本更低 docker compose pull api worker webpull完成后再up -d基本就是重建容器的几秒钟。如果某个镜像拉取一直卡住先确认磁盘剩余空间df -h看一眼磁盘满导致的拉取失败报错和网络问题报错长得挺像。4.2 容器依赖顺序与健康检查怎么看Dify 的 compose 用depends_on加condition: service_healthy控制顺序PostgreSQL 和 Redis 健康之后 api 才起api 起来之后 worker 才起。这套机制大部分时候靠谱但ps里看到healthy之前容器实际已经能响应请求了别被状态吓到。判断是否真起来看三个地方# 1) 所有容器状态关注 STATUS 列是否有 unhealthy 或 Restarting docker compose ps # 2) api 日志正常是 gunicorn 的 worker 启动信息没有 traceback docker compose logs --tail100 api # 3) worker 日志正常是 celery ready 之类的信息 docker compose logs --tail50 workerapi日志里如果反复出现连不上db或redis的记录大概率是.env里的密码和实际起容器的密码不一致——你改了.env但 PostgreSQL 的数据卷里还是旧密码。这种情况要么把密码改回去要么把 db 的数据卷删掉重来仅在还没有数据时可行。worker一直在重启先看日志最后 20 行再docker inspect看退出码。退出码 137 就是被 OOM kill 了跟配置无关纯粹内存不够。4.3 初始化管理员账号并跑通第一个应用容器全绿之后浏览器打开http://你的IP改过端口就带端口会跳到初始化页面设置管理员邮箱和密码。这一步只在数据库为空时出现设置完就再也不出现了——密码忘了只能走重置流程所以第一次就记好。进去之后别急着导数据先跑一个最小闭环验证整条链路在「设置 → 模型供应商」里配一个模型填入可用的 API Key点保存。新建一个「聊天助手」应用模型选刚配的那个。在调试窗口发一句「你好」能正常回话说明 api、worker、模型调用三段都通了。新建一个知识库上传一个几页的 PDF等分段索引完成再回到应用里挂上这个知识库提问。第 4 步才是真正压测环境的一步文档解析走 worker分段索引写向量库检索时读向量库。这一步过了说明向量库、worker、文件存储三处都没问题。第 3 步过了但第 4 步卡住问题基本锁定在向量库或 worker 上。5. 避坑记录五个把我按倒在地的报错这一段是整篇里最像血泪经验的部分。下面五条都是我在不同机器上真实撞过的现象、原因、解决按顺序写撞上了直接对号入座。5.1 向量库没起来api 一直重连现象docker compose ps里只有 db、redis、api、web、nginx、sandbox没有 weaviatedocker compose logs api里反复刷连接weaviate:8080被拒。原因新版 compose 文件用 profiles 管理向量库不带--profile启动时这些服务不会被创建。.env里的VECTOR_STORE只是告诉 api 该连谁不负责把容器拉起来。解决先docker compose config --services确认服务名再用docker compose --profile weaviate up -d启动。已经起了一半的不用down直接带 profile 再up -d就会把缺的补上。5.2 80 端口被占nginx 容器起不来现象docker compose up -d报Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in usenginx 容器状态是Created而不是Up。原因宿主机上已有服务监听 80云服务器镜像预装 nginx 是最常见的情况。解决先sudo ss -lntp | grep :80找到占用进程确认它没用就systemctl stop掉不能停的话改.env的EXPOSE_NGINX_PORT8080然后docker compose up -d nginx重建这一个容器。注意老版本 compose 文件可能没暴露这个变量那就得直接改docker-compose.yaml里 nginx 的 ports 映射改之前先备份。5.3 SECRET_KEY 改完不生效现象.env里明明换成了新生成的密钥登录之后刷新页面就掉线或者接口报 401。原因docker compose restart只重启进程不重新读取.env。环境变量是在容器创建时注入的变量变了必须重建容器。解决# 只重建受影响的三个服务别整个 down 掉 docker compose up -d --force-recreate api worker web同时提醒SECRET_KEY一旦有用户在用就不能随便换换了等于所有人会话失效。要在上线前定好。5.4 内存不够worker 被 OOM kill现象worker容器状态在Restarting之间反复跳docker inspect 容器名 --format {{.State.ExitCode}}输出 137dmesg -T | grep -i killed process能看到对应记录。原因4GB 内存的机器上同时跑 api、worker、向量库、PostgreSQL、Redis一旦做文档索引内存峰值直接越界。解决短期加 swap 顶一下长期升到 8GB。另外可以调小并发.env里有 worker 数量相关的参数不同版本名字略有差异以.env.example里的注释为准把数量从默认值降下来能明显压低峰值代价是索引变慢。5.5 down -v 之后数据没了现象执行过一次docker compose down -v再up -d进去发现应用、知识库、账号全空只剩初始化页面。原因-v是删命名卷的意思数据库和向量库的数据都在卷里。这个参数的本意是「彻底重置」敲之前必须清楚后果。解决只能从备份恢复。所以先养成备份习惯cd /opt/dify/docker # 把 .env 里的变量读进当前 shell避免把库名用户名写死 set -a; source .env; set a # 导出数据库建议加进 crontab 每天跑一次 docker compose exec -T db pg_dump -U $DB_USERNAME $DB_DATABASE \ backup_$(date %F).sql向量库的数据要单独备份富余做法是定期把整个docker/volumes/打包。上传的文件也在这个目录下别只备份数据库。6. 装完怎么验证从健康检查到一次端到端调用装完不等于装好。我见过容器全绿、页面能开但一上传文件就 500 的环境——容器状态只能说明进程活着说明不了链路通。所以最后这一步我会固定跑一套验证五项缺一项都不算完。验证项命令或操作期望结果容器状态docker compose ps所有容器Up有健康检查的是healthy编排语法docker compose config -q无任何输出表示配置可解析后端接口curl -s -o /dev/null -w %{http_code} http://127.0.0.1/console/api/setup返回 200沙箱连通docker compose exec api curl -s http://sandbox:8194/health返回健康响应端到端建应用 → 配模型 → 对话 → 传文档建知识库并检索四步全部成功第三项和第四项最容易被跳过但它们恰好覆盖了两个最容易坏的地方。具体命令cd /opt/dify/docker # 1) 编排文件语法与变量替换结果静默即通过 docker compose config -q # 2) 后端是否响应200 说明 nginx 到 api 这一段通了 curl -s -o /dev/null -w %{http_code}\n http://127.0.0.1/console/api/setup # 3) 沙箱内部连通性代码执行节点依赖它 docker compose exec api curl -s http://sandbox:8194/health # 4) 看最近 200 行日志里有没有 ERROR 级别记录正常应该很少 docker compose logs --tail200 | grep -iE error|traceback | head第 2 项如果返回 502问题在 nginx 到 api 这一段去看docker compose logs nginx返回 000 说明连不上先确认端口对不对。第 3 项失败的话应用里任何涉及代码执行的节点都会报错但聊天功能照常很容易被忽略直到某天用上工作流才炸。端到端那一步我建议加一个容易漏的检查上传一个中文文件名的文档看知识库里的文件名是否正常。文件名编码问题在部分系统的 locale 配置下会出现症状是文件上传成功但列表里显示乱码或者点下载 404。发现这类问题先查.env里的FILES_URL有没有填再查宿主机的 locale。从那以后我每次起新环境都强制先跑docker compose config -q加健康检查三连最后完整走一遍「传文档 → 建知识库 → 检索问答」一项不过就不往下走。这套流程花不了五分钟但能省掉后面排查半天的时间。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?