- 当前仓库里到底有哪两种本地运行方式
- 哪条路径适合"先跑通",哪条路径适合"做源码开发"
- 前端、后端、中间件、Worker 在本地链路里各自承担什么职责
- 哪些配置是硬前提,哪些只是增强项
- 页面能打开但功能不完整时,应该优先排查哪里
本文基于当前仓库实际内容编写,关键依据包括:
- 根目录
README.md docker/README.mdapi/README.mddev/setupdev/start-docker-composedev/start-apidev/start-webdev/start-workerdev/start-beatapi/.env.exampleweb/.env.exampledocker/.env.exampledocker/middleware.env.example
1. 结论与建议
如果只想尽快把 Dify 跑起来,建议直接走下面这条最小路径:
bash
cd docker
cp .env.example .env
docker compose up -d
启动后访问:
text
http://localhost/install
这条路径适合:
- 第一次接触 Dify
- 先验证本机环境是否能跑
- 暂时不关心源码断点调试
如果目标是改前端、调后端、联调接口,建议走源码开发路径:
bash
./dev/setup
./dev/start-docker-compose
./dev/start-api
./dev/start-web
./dev/start-worker
原因如下:
- 当前仓库已经提供了成套开发脚本
- 前后端本机直跑,调试反馈比容器内开发更直接
- 中间件单独用 Docker 承担,既省事又符合 Dify 的实际依赖结构
需要特别明确的一点是:
Dify 不是"起一个前端页面 + 一个后端进程"就算跑起来。
对 Dify 来说,本地运行至少涉及:
webapiPostgreSQLRedis向量数据库
如果你要验证知识库、索引、异步工作流等能力,还应把 worker 一起拉起。
2. 当前仓库中的两条运行路径
2.1 路径一:Docker Compose 整套启动
根目录 README.md 给出的官方最短路径是:
bash
cd docker
cp .env.example .env
docker compose up -d
这条路径的特点是:
- 前端、后端、中间件、Worker 全部由 Compose 管理
- 适合快速验证部署链路
- 不适合频繁做本地源码调试
2.2 路径二:源码开发模式
api/README.md 和 dev/ 目录给出的推荐开发链路是:
./dev/setup./dev/start-docker-compose./dev/start-api./dev/start-web- 需要异步任务时执行
./dev/start-worker - 需要定时任务时执行
./dev/start-beat
这条路径的特点是:
web和api在本机直接运行PostgreSQL、Redis、Weaviate由 Docker 提供- 适合前后端联调和二次开发
3. 本地运行最小组成
当前仓库默认的本地链路可以理解为:
text
浏览器
-> web:3000
-> api:5001
-> PostgreSQL:5432
-> Redis:6379
-> Weaviate:8080
-> worker / beat
其中各部分职责如下:
web: 控制台前端和用户可见页面api: 业务后端、鉴权、应用配置、工作流接口、知识库接口PostgreSQL: 主业务数据Redis: 缓存、Celery Broker、部分运行态协作Weaviate: 默认向量数据库worker: 异步任务消费,如文档处理、索引、部分工作流任务beat: 定时任务调度
需要区分两个层次:
第一层是"页面能不能打开":
web + api + middleware基本够用
第二层是"功能是不是完整":
- 如果不启动
worker,很多异步链路并不完整
这也是 Dify 本地调试最容易误判的地方。
4. 前置条件
4.1 Docker 相关
不管走哪条路径,本机都建议先具备:
DockerDocker Compose
原因不是"所有服务都必须容器化",而是:
- 整套部署路径直接依赖 Compose
- 源码开发路径也依赖 Compose 提供中间件
4.2 Node 与 pnpm
当前仓库前端要求来自两个地方:
web/.nvmrc
text
24
web/package.json
text
node >= 24
因此本机前端开发建议直接使用:
Node 24
前端包管理器为:
text
pnpm@10.27.0
4.3 Python 与 uv
当前仓库后端要求来自 api/pyproject.toml:
text
Python >=3.11,<3.13
也就是建议使用:
Python 3.11- 或
Python 3.12
后端包管理工具已经不是 Poetry,而是:
text
uv
5. 路径一:Docker Compose 整套启动
这是第一次上手 Dify 时最稳的路径。
5.1 启动步骤
进入 docker/ 目录:
bash
cd /home/xx/project/workflow/self/dify/docker
复制环境文件:
bash
cp .env.example .env
启动整套服务:
bash
docker compose up -d
5.2 启动后访问地址
根据根目录 README.md,首次安装入口为:
text
http://localhost/install
5.3 这条路径的优点
- 最接近"按官方部署方式直接跑起来"
- 中间件、前后端、Worker 都被 Compose 统一管理
- 适合先判断机器环境是否满足要求
5.4 这条路径的局限
- 不适合高频改前后端源码
- 本机文件改动不一定按你期望的方式即时反馈到容器
- 如果你的目标是断点调试,这条路径不够顺手
5.5 常用检查命令
看服务状态:
bash
docker compose ps
看日志:
bash
docker compose logs -f
停止服务:
bash
docker compose down
6. 路径二:源码开发模式
这是更适合长期开发和联调的路径。
6.1 这条路径到底做了什么
源码开发模式不是"完全脱离 Docker",而是:
web本机运行api本机运行PostgreSQL/Redis/Weaviate用 Docker 跑
这样设计的好处是:
- 前端热更新直接可用
- 后端日志、断点、重启更直接
- 复杂中间件不需要在本机重复安装和维护
7. 源码开发模式的准备工作
7.1 执行初始化脚本
在仓库根目录执行:
bash
cd /home/xx/project/workflow/self/dify
./dev/setup
当前 dev/setup 会完成以下工作:
- 复制
api/.env.example到api/.env - 复制
web/.env.example到web/.env.local - 复制
docker/middleware.env.example到docker/middleware.env - 在
api/下执行uv sync --group dev - 在
web/下执行pnpm install
7.2 初始化后应检查的文件
至少检查下面三个文件:
api/.envweb/.env.localdocker/middleware.env
其中最重要的是 api/.env。
7.3 SECRET_KEY 是硬前提
api/.env.example 里:
text
SECRET_KEY=
这个值不应保持为空。
可以直接生成:
bash
openssl rand -base64 42
然后写入 api/.env。
如果这个值为空,后续常见问题包括:
- 初始化流程异常
- 登录态相关行为异常
- Cookie / Session 相关问题难以排查
8. 中间件启动链路
8.1 启动命令
在仓库根目录执行:
bash
./dev/start-docker-compose
当前脚本实际执行的是:
bash
docker compose -f docker/docker-compose.middleware.yaml --profile postgresql --profile weaviate -p dify up -d
8.2 这一步实际会拉起什么
根据 docker/README.md 和当前脚本,源码开发模式默认会拉起:
PostgreSQLRedisWeaviate
这里要注意一个常见误区:
虽然脚本名称里写的是 start-docker-compose,但它并不是把 Dify 全家桶都容器化启动。
它只是把"源码开发模式所需的中间件"拉起来。
8.3 为什么默认是 PostgreSQL + Weaviate
这是当前仓库的默认开发组合:
DB_TYPE=postgresqlVECTOR_STORE=weaviate
如果你不准备改数据库和向量库选型,按默认值即可。
9. 后端 API 启动链路
9.1 启动命令
新开一个终端,在仓库根目录执行:
bash
./dev/start-api
9.2 当前脚本的实际行为
当前 dev/start-api 先执行数据库迁移:
bash
uv run flask db upgrade
然后启动 Flask:
bash
uv run flask run --host 0.0.0.0 --port=5001 --debug
9.3 后端默认地址
本地默认地址为:
text
http://localhost:5001
9.4 为什么这一步很关键
很多人会把"前端页面打开了"误认为 Dify 已经启动成功。
实际上只要 api 没起来,前端只是壳。
后续这些行为都依赖 api:
- 初始化安装
- 登录
- 应用配置读取
- 模型供应商配置
- 知识库接口
- 工作流接口
10. 前端 Web 启动链路
10.1 启动命令
再开一个终端,在仓库根目录执行:
bash
./dev/start-web
10.2 当前脚本的实际行为
它会进入 web/ 目录执行:
bash
pnpm install && pnpm dev:inspect
10.3 前端默认地址
text
http://localhost:3000
10.4 前后端是怎么接上的
web/.env.example 里已经给出本地开发默认值:
text
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
因此在默认情况下:
- 前端跑
3000 - 后端跑
5001 - 前端会自动把请求发到本地
5001
如果你没有修改这些变量,就不应该再额外手动改一遍。
11. Worker 与 Beat 的作用
11.1 Worker 不是可有可无
启动命令:
bash
./dev/start-worker
当前脚本会根据社区版默认队列启动 Celery Worker。
对 Dify 来说,下面这些能力很容易依赖 Worker:
- 文档导入
- 文档切片
- 向量索引
- 部分工作流异步执行
- 插件相关后台处理
所以要区分两个结论:
- 页面能打开,不代表系统功能完整
- 不启动 Worker,很多异步能力并不成立
11.2 Beat 的定位
启动命令:
bash
./dev/start-beat
Beat 的作用是调度定时任务。
不是所有本地开发场景都必须启动它,但在下面这些情况下建议一起开:
- 你要尽量贴近完整运行态
- 你在排查周期性任务
- 你在观察保活、清理、轮询类任务
12. 推荐启动顺序
当前仓库最稳的本地开发顺序如下:
./dev/setup./dev/start-docker-compose./dev/start-api./dev/start-web- 浏览器访问
http://localhost:3000 - 需要异步任务时执行
./dev/start-worker - 需要定时任务时执行
./dev/start-beat
这个顺序的核心逻辑是:
- 先保证配置文件和依赖完整
- 再保证数据库、Redis、向量库可达
- 再跑 API
- 最后跑前端和后台任务
如果顺序反过来,排障时会明显更乱。
13. 运行完成后的关键检查项
13.1 中间件是否已拉起
可以执行:
bash
docker ps
或者更精确地看当前这组服务:
bash
docker compose -f docker/docker-compose.middleware.yaml -p dify ps
13.2 端口是否符合预期
当前本地默认应重点关注:
30005001543263798080
其中:
3000是前端5001是后端5432是 PostgreSQL6379是 Redis8080是 Weaviate
13.3 前端环境变量是否仍指向本地后端
重点看 web/.env.local 中是否仍为:
text
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
13.4 后端数据库和缓存地址是否仍指向本地中间件
重点看 api/.env 中是否仍为:
text
DB_HOST=localhost
DB_PORT=5432
REDIS_HOST=localhost
REDIS_PORT=6379
WEAVIATE_ENDPOINT=http://localhost:8080
如果这里被改成容器内地址或其他机器地址,而你自己又没意识到,本地启动经常会表现成"服务起来了但功能全挂"。
14. 常见问题与排查顺序
14.1 页面能打开,但初始化或登录失败
优先检查:
api是否真的在5001成功启动api/.env的SECRET_KEY是否为空web/.env.local是否仍然指向localhost:5001
这一类问题最常见的根因不是前端,而是后端配置没准备完整。
14.2 前端起来了,但接口请求全失败
优先检查:
./dev/start-api终端里有没有报错uv run flask db upgrade有没有失败PostgreSQL和Redis是否真的已启动
这类问题的本质通常是:
- 前端不是没起来
- 而是后端或中间件没接上
14.3 知识库导入、切片、索引没反应
优先检查:
worker是否已启动Weaviate是否已启动api/.env中VECTOR_STORE和WEAVIATE_ENDPOINT是否仍匹配当前环境
这类问题最容易被误判成"页面功能异常",实际上很多时候是异步链路没起来。
14.4 改了前端代码但浏览器没看到变化
先确认你当前到底跑的是哪条路径:
- 如果你跑的是整套
docker compose - 那你改本机源码后,未必会按源码开发模式即时反映
如果你希望获得典型的前端开发体验,应使用:
bash
./dev/start-web
这个问题本质上不是"前端热更新失效",而是"运行方式混用了"。
14.5 API 能起,页面也能开,但很多功能报异步错误
优先检查:
worker是否已启动- Redis 是否正常
- Worker 终端是否持续报连接错误或队列错误
这说明你已经跑通了同步链路,但异步链路还没闭环。
15. 两条路径应该怎么选
15.1 只想快速验证 Dify 能否运行
建议选择:
bash
cd docker
cp .env.example .env
docker compose up -d
这是"部署优先"的路径。
15.2 想做源码阅读、联调和二次开发
建议选择:
bash
./dev/setup
./dev/start-docker-compose
./dev/start-api
./dev/start-web
./dev/start-worker
这是"开发优先"的路径。
15.3 不建议一开始就混用两条路径
最常见的问题不是命令不会写,而是:
- 一部分服务来自 Docker 全家桶
- 一部分服务来自本机源码模式
- 自己又不清楚当前哪个端口对应哪组进程
一旦混用,排障成本会明显上升。
16. 结语
理解 Dify 的本地运行方式,关键不是死记命令,而是先建立一个判断:
Dify 本质上是一组协作服务,而不是一个单体进程。
因此更稳妥的本地实践顺序应该是:
- 先用
docker compose验证整套环境可运行 - 再切到源码开发模式做调试和二开
这样做的好处是:
- 先排除环境级问题
- 再进入代码级问题
- 避免一开始就在前端、后端、中间件、Worker 之间盲查
如果后续继续扩展这组笔记,最值得写的下一篇应是:
Dify 本地调试与断点排障笔记Dify Worker / Celery 运行链路笔记Dify 前后端联调与环境变量关系笔记