dify 专题01 基础环境搭建
0. 写在最前面
0.1 为什么要写这个专栏
自身工作原因,接触了一些厂商,只能说,dify因为比较早的开源时间和友好的用户体验获取了不少用户和star数,虽然coze最近也开源了,但是按照自身目前的了解,dify工作流在某种意义上已经取了部分先机。
对看官而言,希望专栏可以降低学习成本,拉平学习梯度,少走弯路,多点时间做自己喜欢的事情。
对于自己而言,写这个专栏,权当是使用费曼学习法鞭笞自己好好学习。
0.2 有了dify docs为什么还要写dify专栏
dify的官方文档地址为 :https://docs.dify.ai/zh-hans/introduction
dify的源码地址为:https://github.com/langgenius/dify/
文档写的很规整,源码也很规范,但是在实际工程中会碰到很多问题,尤其是需要本地化私有化部署的场景,而这些问题并没有显式的写在文档中,专栏的期望是以本地私有化部署的角度 结合源码的方式记录并解释各种dify出现的问题,尽可能的以低门槛的方式将问题说明白。
1. 基础环境的内容
简单说明一下,dify分为社区版和商业版,目前社区版本开源,而商业版本收费,具体的收费标准各家代理和官方可能会有区别,这里过多描述,专栏主要以社区版本进行说明。
dify的云服务是开箱即用的dify云服务,相当于环境由dify帮你搞定,云上部署,不属于本专栏讨论的部分。
dify社区本有两种方式进行部署
- docker compose部署:通过dify源码的 docker-compose环境进行一键部署,借助docker环境,不需要了解源码就可以本地私有化部署一套dify环境
- 源码启动:中间件需要先使用docker compose启动,例如 PostgreSQL / Redis / sandbox / plugin-daemon 等,前段和后端可以使用代码启动,或者通过pycharm/vscode进行单步调试
基于上述说明,可以得出,我们需要准备的前提条件
docker/docker comopose 环境,请参考
https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/local-source-code#%E4%BD%BF%E7%94%A8-docker-compose-%E5%90%AF%E5%8A%A8%E4%B8%AD%E9%97%B4%E4%BB%B6

当下的硬件环境一般都符合手册的要求,这里需要注意的是,如果了解dify源码或者尝试过源码级别调试的小伙伴应该知道,dify需要在类unix环境下比较好做源码级别的调试,macos和 linux版本先天是ok的,如果使用windows的小伙伴稍微会比较麻烦,需要搭建wsl2环境,微软的wsl官方文档位置为
https://learn.microsoft.com/zh-cn/windows/wsl/
对于win10的系统版本要求为
https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-2---check-requirements-for-running-wsl-2

我目前的win10系统版本信息如下:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
这篇文档以Win10 Wsl2 作为linux环境对 基础环境作为介绍,ubantu22.04可以参考linux环境部分
1.1 win10 环境
关于什么是wsl2,这个问题可以简单的认为 windows以子系统的方式运行 linux。
wsl2 适用于 Linux 的 Windows 子系统(WSL)允许开发人员直接在 Windows 上运行 GNU/Linux 环境(包括大多数命令行工具、实用工具和应用程序),无需传统虚拟机或双启动设置的开销。

建议使用win10 wsl2 的小伙伴先通篇阅读 微软官方的 wsl文档
https://learn.microsoft.com/zh-cn/windows/wsl/
出了文档之外,微软还提供了很多有价值的视频教程(全在油管上,需要科学上网)

1.1.1 wsl2安装
在安装之前,我们先简单说明一下 wsl2 和 wsl的区别

对于wsl1来说,是将linux的命令解释成windows NT内核可以执行的命令,这种做法势必会导致极大的工作量和工作限制。根据软件规则,如果难以解耦,那么就加上一个中间层,所以wsl2 使用了 hypervisor 虚拟化平台。
1.1.1.1 配置window wsl子系统和硬件虚拟化功能

打开 启动或者关闭windows功能,然后勾上这两个勾勾

1.1.1.2 查看cpu虚拟化
可以参考 微软文档 Windows和Windows Server上的Hyper-V的系统要求
https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/
https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/host-hardware-requirements?pivots=windows#:%7E:text=on%20Windows%20Server.-,General%20requirements,the%20processor%20must%20have%20SLAT.
通过任务管理器查看 CPU虚拟化是否已经启用,目前的cpu一般都是默认打开,如果没有打开,那么通过bios进行设置,这里不做具体介绍

1.1.1.3 wsl2安装
对于wsl2的安装,官方文档的位置如下:
https://learn.microsoft.com/zh-cn/windows/wsl/install
我们参考这个文档进行操作
右键单击并选择“以 管理员 身份运行”,在管理员模式下打开 PowerShell,输入 wsl --install 命令,然后重新启动计算机



wsl --install
安装完了之后需要重启一次
1.1.2 将wsl2 配置为默认版本
需要通过命令将 wsl配置为 wsl2版本
wsl --set-default-version 2

1.1.3 下载linux发行版
下载发行版可以通过 使用 Microsoft 商店安装,可以使用连接下载发行版,也可以使用 wsl 命令进行下载安装,具体可以参考
下载的前提是需要能够 访问微软地址
https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package
https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-6---install-your-linux-distribution-of-choice
https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#downloading-distributions
一般我使用的是 命令进行安装
先看看我们目前的wsl列表
PS C:\Users\djz> wsl -l -v
NAME STATE VERSION
* ubantu-22.04 Running 2
docker-desktop-restored Stopped 2
docker-desktop Stopped 2
PS C:\Users\djz>
目前我的列表中存在 的 WSL 发行版为 ubantu-22.04 、docker-desktop-restored/docker-desktop , 因为我之前先安装了win10的docker,所以docker-desktop-restored/docker-desktop 被wsl2 认为是自动安装的两个发行版
ubantu-22.04 是我自己的安装的发行版
对于STATE列来说,Running代表的是发行版 ubantu-22.04 目前是运行的 ,Stopped表示不运行,Version表示使用的是wsl2架构
这里以kali为例
先查看online 的版本
wsl --list --online

列表显示的是可用的linux发行版,我们选择 kili-linux
wsl --install -d kali-linux

安装完成后日志如下

需要输入用户名,然后又输入密码
输入之后自动进入linux环境

输入exit后可以退出

1.1.4 将发行版移动到别的盘
查看一下发行版本列表
PS C:\Users\djz> wsl -l --all -v
NAME STATE VERSION
* ubantu-22.04 Running 2
docker-desktop-restored Stopped 2
docker-desktop Stopped 2
kali-linux Stopped 2
默认的linux发行版是安装在C盘, 我们不希望C盘爆炸,所以需要把kali-linux移动到 别的盘,我们需要通过导出kali-linux到指定路径F:\wsl2\kali,然后卸载掉wsl系统中的发行版,再到指定路径F:\wsl2\kali导入发行版的方式 达到 发行版转移的目的
从文件的角度上发行版的文件为 ext4.vhdx ,参考我之前安装的ubantu22.04

我们开始转移
wsl --export kali-linux F:\wsl2\kali\kali-linux.tar

执行结果如下:

执行成功结果:

此时我们看到指定位置文件如下

1.1.5 卸载wsl 列表中的kali

我们现在卸载这个文件
PS C:\Users\djz> wsl --unregister kali-linux
正在注销。
操作成功完成。

1.1.6 从指定位置导入 kali
去到 F:\wsl2\kali

使用命令导入
wsl --import kali-linux-01 F:\wsl2\kali\ ./kali-linux.tar


查看列表

PS F:\wsl2\kali> wsl -l --all -v
NAME STATE VERSION
* ubantu-22.04 Running 2
docker-desktop-restored Stopped 2
kali-linux-01 Stopped 2
docker-desktop
我们可以看到 kali-linux-01
1.1.6 启动 kali-linux-01

我们看到 kali-linux-01 已经启动
如果觉得window 的 powershell ui和颜色方案比较丑,可以下载 windows terminal

1.2 linux环境
1.2.1 conda环境安装
明确一下方向,我们主要是搞AI开发或者AI算法,一般来说,使用的代码都是python,dify也好,或者机器学期也好,目前基本上都是python环境,而python环境隔离推荐使用conda
conda 官网
https://www.anaconda.com/

https://www.anaconda.com/download
滑到下边

https://www.anaconda.com/download/success
我们使用miniconda x86架构

为什么不装 Distribution Installers? 因为试过会挂掉,具体原因暂不做讨论,直接使用miniconda installers
把下载好的 放在 F:\wsl2\ubantu2204

(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204# ls
Miniconda3-latest-Linux-x86_64.sh code ext4.vhdx ubantu2204.tar
可以参考 anaconda 的 文档
https://www.anaconda.com/docs/main
可以直接用 sh 执行 Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
步骤可以参考
https://www.anaconda.com/docs/getting-started/miniconda/install#macos-linux-installation:manual-shell-initialization
如果没有特定要求,可以一路yes
看到 “Thank you for installing Miniconda3!”之后
source ~/.bashrc
1.2.2 conda环境创建基于pytorch的环境
这里我还是使用之前的 ubantu2204, 我们需要使用conda 进行环境隔离, 这里基于 python 3.12 版本,创建名为 pytorch251 的环境
conda create -n pytorch251 python=3.12 -y
这里我使用conda info查看环境
(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204# conda info
active environment : base
active env location : /root/miniconda3
shell level : 1
user config file : /root/.condarc
populated config files : /root/miniconda3/.condarc
/root/.condarc
conda version : 25.3.1
conda-build version : not installed
python version : 3.13.2.final.0
solver : libmamba (default)
virtual packages : __archspec=1=haswell
__conda=25.3.1=0
__cuda=12.8=0
__glibc=2.35=0
__linux=6.6.87.1=0
__unix=0=0
base environment : /root/miniconda3 (writable)
conda av data dir : /root/miniconda3/etc/conda
conda av metadata url : None
channel URLs : https://mirrors.ustc.edu.cn/anaconda/pkgs/free/linux-64
https://mirrors.ustc.edu.cn/anaconda/pkgs/free/noarch
https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/linux-64
https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/noarch
https://repo.anaconda.com/pkgs/main/linux-64
https://repo.anaconda.com/pkgs/main/noarch
https://repo.anaconda.com/pkgs/r/linux-64
https://repo.anaconda.com/pkgs/r/noarch
package cache : /root/miniconda3/pkgs
/root/.conda/pkgs
envs directories : /root/miniconda3/envs
/root/.conda/envs
platform : linux-64
user-agent : conda/25.3.1 requests/2.32.3 CPython/3.13.2 Linux/6.6.87.1-microsoft-standard-WSL2 ubuntu/22.04.5 glibc/2.35 solver/libmamba conda-libmamba-solver/25.4.0 libmambapy/2.0.5 aau/0.7.0 c/. s/. e/.
UID:GID : 0:0
netrc file : None
offline mode : False
可以看到添加了中科大的镜像源,命令为
conda config --remove-key channels
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/pytorch/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/nvidia/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/
之后我们安装pytorch 2.5.1
conda install pytorch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 pytorch-cuda=12.4 -y
安静等待环境安装完成
1.2.3 验证pytorch环境
我们创建一个.py 环境

使用如下代码进行验证
import torch
def verify_pytorch():
# 1. 检查 PyTorch 版本
print(f"PyTorch 版本: {torch.__version__}")
# 2. 检查 CUDA 是否可用
cuda_available = torch.cuda.is_available()
print(f"CUDA 可用: {cuda_available}")
if cuda_available:
# 3. 打印 CUDA 相关信息(如设备数量、当前设备、计算能力等)
print(f"CUDA 设备数量: {torch.cuda.device_count()}")
print(f"当前 CUDA 设备: {torch.cuda.current_device()}")
print(f"CUDA 设备名称: {torch.cuda.get_device_name(0)}")
print(f"CUDA 计算能力: {torch.cuda.get_device_capability(0)}")
# 4. 测试 GPU 上的张量运算
print("\n===== 测试 GPU 张量运算 =====")
# 在 GPU 上创建随机张量
gpu_tensor1 = torch.randn(3, 3, device="cuda")
gpu_tensor2 = torch.randn(3, 3, device="cuda")
print("GPU 张量 1:\n", gpu_tensor1)
print("GPU 张量 2:\n", gpu_tensor2)
# 执行基本运算(矩阵乘法)
gpu_result = torch.matmul(gpu_tensor1, gpu_tensor2)
print("GPU 矩阵乘法结果:\n", gpu_result)
# 将结果转移到 CPU 并打印
cpu_result = gpu_result.cpu()
print("转移到 CPU 的结果:\n", cpu_result)
else:
# 5. 若 CUDA 不可用,测试 CPU 上的张量运算
print("\n===== 测试 CPU 张量运算 =====")
cpu_tensor1 = torch.randn(3, 3)
cpu_tensor2 = torch.randn(3, 3)
print("CPU 张量 1:\n", cpu_tensor1)
print("CPU 张量 2:\n", cpu_tensor2)
cpu_result = torch.matmul(cpu_tensor1, cpu_tensor2)
print("CPU 矩阵乘法结果:\n", cpu_result)
# 6. 验证自动求导功能
print("\n===== 测试自动求导 =====")
x = torch.tensor([2.0], requires_grad=True)
y = x **2 + 3*x + 1
y.backward() # 反向传播
print(f"函数 y = x² + 3x + 1 在 x=2 处的导数: {x.grad}") # 理论结果为 2*2 + 3 = 7
if __name__ == "__main__":
verify_pytorch()

在终端运行这段代码,运行结果如下
(pytorch251) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/zerotohero# python pythorch_test.py
PyTorch 版本: 2.5.1
CUDA 可用: True
CUDA 设备数量: 1
当前 CUDA 设备: 0
CUDA 设备名称: NVIDIA GeForce RTX 2080 Ti
CUDA 计算能力: (7, 5)
===== 测试 GPU 张量运算 =====
GPU 张量 1:
tensor([[-0.7642, -0.5771, 0.9036],
[ 0.4798, -0.0338, -1.3035],
[ 2.2631, 0.7851, 1.1472]], device='cuda:0')
GPU 张量 2:
tensor([[ 0.5776, 0.3158, 1.3707],
[ 2.2344, -0.8844, 0.6217],
[-0.8354, 0.3117, 0.1017]], device='cuda:0')
GPU 矩阵乘法结果:
tensor([[-2.4858, 0.5507, -1.3144],
[ 1.2906, -0.2249, 0.5042],
[ 2.1029, 0.3781, 3.7068]], device='cuda:0')
转移到 CPU 的结果:
tensor([[-2.4858, 0.5507, -1.3144],
[ 1.2906, -0.2249, 0.5042],
[ 2.1029, 0.3781, 3.7068]])
===== 测试自动求导 =====
函数 y = x² + 3x + 1 在 x=2 处的导数: tensor([7.])

2. 部署dify
dify私有化本地部署的可以参考 https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/readme
总的来说,分为两种,一是 docker compose / docker ,另一种是源码启动,这里不讨论宝塔面板部署
2.0 代码下载
官方的代码下载方式为
# 假设当前最新版本为 0.15.3
git clone https://github.com/langgenius/dify.git
正常情况下耐心等待一段时间,就会clone 完成
如果网络有问题,那么可以选择 download zip

然后解压
代码下载好了之后大概如下

2.1 docker compose 部署
2.1.1 配置环境和docker拓扑
docker compose 启动
到 docker 目录下
/mnt/f/wsl2/ubantu2204/code/dify/dify/docker

复制环境配置文件
cp .env.example .env

我们可以看看这个文件里写了什么,文件很长,里边大致是 一些组件的相关配置,比如端口、地址、属性等配置

docker目录下有这么一个文件 docker-compose.png ,这个文件描述了大致的 docker 拓扑


后续再详细描述这个部分,我们知道最终会有几个docker容器生成
2.1.2 wsl2 执行 docker compose 与 docker desctop
执行docker compose 命令
docker compose up -d
出现如下日志
(pytorch251) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/docker# docker compose up -d
The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.
For details about using Docker Desktop with WSL 2, visit:
https://docs.docker.com/go/wsl2/
解决的办法:
启动win10 的docker desctop
打开 Docker Desktop → 进入 Settings(设置) → 选择 Resources(资源) → WSL Integration(WSL 集成) →
勾选你正在使用的 WSL 2 发行版(如 Ubuntu 22.04)→ 点击 Apply & Restart 重启 Docker Desktop。


注意,如果没有科学上网,那么可以将阿里云的docker源配置到docker引擎中

实测中科大的镜像源更稳定
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirrors.ustc.edu.cn/docker-ce/"
]
}
在wsl中验证docker 是否可用

如果 docker仍旧从官方docker hub拉镜像,那么 通过
wsl --shutdown
过一段时间重启
2.1.3 执行 docker compose

(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/docker# docker compose up -d
[+] Running 19/83
⠇ nginx [⠀⠀⠀⠀⠀⠀⠀] Pulling 55.8s
⠇ weaviate [⠀⠀⠀⠀] Pulling 55.8s
⠇ db [⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀] Pulling 55.8s
⠧ sandbox [⡀⡀⠀⠀⠀⠀⠀⠀⠀⠀] Pulling 55.8s
⠧ worker_beat Pulling 55.8s
⠧ worker [⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀] Pulling 55.8s
⠧ api Pulling 55.8s
⠧ plugin_daemon [⣿⣿⣿⣿⣿] 509.8MB / 510.9MB Pulling 55.8s
⠧ ssrf_proxy [⣿⣄⣿] 47.92MB / 72.61MB Pulling 55.8s
⠧ redis [⠀⠀⠀⠀⠀⠀] Pulling 55.8s
✔ web Pulled 43.7s
耐心等待一段时间

哦豁,报错了

我们使用 docker logs 查看 日志
docker logs docker-db-1
从日志可以明确看出,问题根源是 PostgreSQL 容器没有权限修改数据目录 /var/lib/postgresql/data/pgdata 的权限,这在 WSL2 中挂载 Windows 路径时非常常见(Windows 文件系统的权限与 Linux 不兼容)。
有两个解决办法
1 临时解决办法:
可直接给本地挂载的数据库目录赋予 777 权限(宽松但有效):
# 假设 docker-compose.yml 中 db 服务的挂载路径是 ./data/db(需根据实际配置修改)
sudo chmod -R 777 ./data/db
# 重启服务
docker compose down && docker compose up -d
2 在docker compose 中指定uid 匹配
PostgreSQL 容器内部默认使用 postgres 用户(UID 为 999),可在 docker-compose.yml 中强制容器使用当前用户的 UID,避免权限冲突:
编辑 docker-compose.yml,找到 db 服务的配置,添加 user: "${UID}:${GID}":
services:
db:
image: postgres:xxx # 保持原镜像版本
volumes:
- ./data/db:/var/lib/postgresql/data/pgdata # 原挂载路径
environment:
- POSTGRES_PASSWORD=xxx # 保持原环境变量
- PGDATA=/var/lib/postgresql/data/pgdata
user: "${UID}:${GID}" # 添加此行,使用当前用户的 UID/GID
# 其他配置(如 ports、healthcheck 等)保持不变
然后重启服务:
# 刷新环境变量并启动
export UID GID # 确保 UID/GID 被正确识别
docker compose down && docker compose up -d
3 改用 WSL2 内部路径挂载(彻底避免权限问题)
挂载的是 Windows 路径(如 /mnt/f/...),权限问题很难彻底解决,建议将数据目录放在 WSL2 内部路径(如 ~/code/...):
3.1 在 WSL2 中创建内部目录:
mkdir -p ~/code/dify/dify/docker/data/db
3.2 修改 docker-compose.yml 中 db 服务的挂载路径
volumes:
- ~/code/dify/dify/docker/data/db:/var/lib/postgresql/data/pgdata # 改为 WSL 内部路径
3.3 重启服务
docker compose down && docker compose up -d
这里简单使用方案1
(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/docker# sudo chmod -R 777 ./data/db
(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/docker# docker compose down && docker compose up -d
执行结果如下:
使用 docker ps -a 观察

我们通过win10 localhost访问

为什么可以访问?
我们打开docker desctop

这里我们可以看到 docker desctop和我们在wsl中的docker容器是一样的,至此认为 docker compose启动完成
注册时候可以进入

2.2 源码启动
可以参考 官网的文档进行操作
https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/local-source-code
2.2.1 前提条件
前文提过,再次啰嗦一嘴

先down掉之前启动的docker 容器
(base) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/docker# docker compose down
[+] Running 9/11
✔ Container docker-worker_beat-1 Removed 0.1s
✔ Container docker-plugin_daemon-1 Removed 0.1s
✔ Container docker-weaviate-1 Removed 0.6s
⠼ Container docker-ssrf_proxy-1 Stopping 3.5s
✔ Container docker-sandbox-1 Removed 0.5s
✔ Container docker-nginx-1 Removed 0.1s
✔ Container docker-worker-1 Removed 0.1s
✔ Container docker-api-1 Removed 0.0s
⠼ Container docker-web-1 Stopping 3.4s
✔ Container docker-db-1 Removed 0.0s
✔ Container docker-redis-1 Removed 0.6s
使用 Docker Compose 启动中间件
进入docker 目录
cp middleware.env.example middleware.env
docker compose -f docker-compose.middleware.yaml up -d

通过 docker ps -a 查看启动的容器

2.2.2 设置后端服务
参考 https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/local-source-code#%E8%AE%BE%E7%BD%AE%E5%90%8E%E7%AB%AF%E6%9C%8D%E5%8A%A1
2.2.2.1 环境准备
这里 dify 使用 pyenv 管控 python环境,这里我们使用conda
conda create -n dify_v170 python=3.12 -y

激活环境
conda activate dify_v170
2.2.2.2 启动导航服务
到api目录下
(dify_v170) root@DESKTOP-UK0947P:/mnt/f/wsl2/ubantu2204/code/dify/dify/api# pwd
/mnt/f/wsl2/ubantu2204/code/dify/dify/api
准备环境变量配置文件
cp .env.example .env
生成随机密钥并替换 .env 文件中的 SECRET_KEY 值
awk -v key="$(openssl rand -base64 42)" '/^SECRET_KEY=/ {sub(/=.*/, "=" key)} 1' .env > temp_env && mv temp_env .env
安装依赖 使用 uv 管理依赖。 通过运行以下命令使用 uv 安装所需依赖
uv sync
命令执行出错

因为我没有安装 ua,这里我们使用 snap 进行安装
snap install astral-uv
继续报错

stral-uv 这个 snap 包使用了 classic 模式(无沙箱限制),需要显式允许才能安装。解决方法如下
sudo snap install astral-uv --classic

很慢,感觉没有任何进展,我们使用 pip 进行安装
pip配置为阿里源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
安装uv
pip install uv

生成随机密钥并替换 .env 文件中的 SECRET_KEY 值
awk -v key="$(openssl rand -base64 42)" '/^SECRET_KEY=/ {sub(/=.*/, "=" key)} 1' .env > temp_env && mv temp_env .env
使用 uv 安装所需依赖
uv sync

如果速度过慢,或者 出现超时问题, 指定阿里源进行同步
uv sync --index-url https://mirrors.aliyun.com/pypi/simple/
如果网速没有问题,一般几分钟就ok了

执行数据库迁移 执行数据库迁移到最新版本
uv run flask db upgrade
如果又碰到这样的错误

请参考 git issue
https://github.com/langgenius/dify/issues/5731

哥们儿也是绷不住了
照着做了一发,果然ok

重新来一发

回到api目录
uv run flask db upgrade

启动 API 服务

启动 Worker 服务
https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/local-source-code#%E5%90%AF%E5%8A%A8-worker-%E6%9C%8D%E5%8A%A1
要从队列中消费异步任务,例如数据集文件导入和数据集文档更新,需要启动woker服务
uv run celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace


至此后端启动完成
2.2.2.3 启动 Web 服务
进入web目录
(dify_v170) root@DESKTOP-UK0947P:/home/djz/code/dify/dify# cd web/
(dify_v170) root@DESKTOP-UK0947P:/home/djz/code/dify/dify/web#
在启动web 服务之前,需要安装 nodejs v22 和 pnpm v10
https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/local-source-code#%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87-2
nodejs安装
https://nodejs.org/zh-cn/download

安装依赖
pnpm install --frozen-lockfile
报错了

此时 需要先安装node
官网地址为
https://nodejs.org/zh-cn/download

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
用这个命令下载会很慢,建议使用下边这条命令
NVM_INSTALL_GITHUB_REPO=mirrors/nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
执行结果
(dify_v170) root@DESKTOP-UK0947P:/home/djz/code# NVM_INSTALL_GITHUB_REPO=mirrors/nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 16631 100 16631 0 0 24441 0 --:--:-- --:--:-- --:--:-- 24457
=> Downloading nvm from git to '/root/.nvm'
=> Cloning into '/root/.nvm'...
remote: Enumerating objects: 383, done.
remote: Counting objects: 100% (383/383), done.
remote: Compressing objects: 100% (326/326), done.
remote: Total 383 (delta 43), reused 178 (delta 29), pack-reused 0 (from 0)
Receiving objects: 100% (383/383), 392.12 KiB | 64.00 KiB/s, done.
Resolving deltas: 100% (43/43), done.
* (HEAD detached at FETCH_HEAD)
master
=> Compressing and cleaning up git repository
=> Appending nvm source string to /root/.bashrc
=> Appending bash_completion source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
然后执行
\. "$HOME/.nvm/nvm.sh"
nvm install 22

node -v

(dify_v170) root@DESKTOP-UK0947P:/home/djz/code# nvm current
v22.18.0
(dify_v170) root@DESKTOP-UK0947P:/home/djz/code# npm -v
10.9.3
接下来安装 pnpm
配置源为阿里源
npm config set registry https://registry.npmmirror.com
安装
npm install -g pnpm@10

最终结果
(dify_v170) root@DESKTOP-UK0947P:/home/djz/code# pnpm --version
10.14.0

进入web目录,安装依赖
pnpm install --frozen-lockfile

安装完成后

编辑.env.local文件,使用win10的编辑器 nodepad–


# For production release, change this to PRODUCTION
NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
# The deployment edition, SELF_HOSTED or CLOUD
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# SENTRY
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_SENTRY_ORG=
NEXT_PUBLIC_SENTRY_PROJECT=
保存完了开始构建
pnpm build

这里需要几分钟时间

构建完成,可以启动web服务了
pnpm start

浏览器输入
http://localhost:3000/install

注册

点击设置之后我们可以看到日志

基本上没有什么问题

3. vscode单步调试
之前写过一篇 文章, 用pycharm 远程裸金属ubantu的文章,这里远程wsl2也差不多,因为pycharm需要专业版才有远程功能,这里尝试使用vscode进行单步调试源码,这里使用vscode单步调试 api service 模块
3.1 wsl2 sshd服务安装与配置
3.1.1 sshd服务安装
因为vscode remote ssh方式打开dify的api项目需要用到sshd服务,wsl默认没有这个服务,需要手工添加
sudo apt update && sudo apt install openssh-server

3.1.2 修改配置文件
vi /etc/ssh/sshd_config
打开如下两行代码
Port 22
PasswordAuthentication yes

3.1.3 启动sshd
service ssh start

3.2 vscode安装插件
以下这几个组件都装上,如果遇到网络问题,需要科学上网,或者到网上找好心人的压缩包

安装成功之后点击如下按钮



这里补充一下 Connect to WSL和Connect to WSL using Distro的区别
连接方式与灵活性
Connect to WSL:选择该选项后,VS Code 会自动检测并连接到当前默认的 WSL 发行版 。如果你的系统中只安装了一个 WSL 发行版,那么它会直接连接到这个发行版。这种方式比较便捷,适用于系统中只有一个 WSL 发行版,或者你习惯使用默认发行版进行开发的场景。Connect to WSL using Distro...:此选项允许你从系统中已安装的所有 WSL 发行版列表中,手动选择要连接的特定发行版。 当你的系统安装了多个 WSL 发行版(例如同时安装了 Ubuntu 和 Debian ),且你需要在不同发行版中进行不同项目开发时,该方式提供了更多的灵活性,可以精准连接到所需的发行版。
使用场景举例
- 场景一:单一发行版开发
如果你在 Windows 系统上安装了 Ubuntu 作为 WSL 发行版,且日常开发工作都在这一个发行版中进行,那么使用Connect to WSL就可以快速连接进入开发环境,不需要额外选择。比如你日常开发 Node.js 应用,直接通过Connect to WSL连接到默认的 Ubuntu 环境,就可以开始编写、调试代码。 - 场景二:多发行版管理
假设你在开发一个项目时,需要在 Ubuntu 中进行 Python 项目开发,而在 Debian 中进行 C++ 项目的编译和测试。这时,Connect to WSL using Distro...就能派上用场,你可以根据项目需求,手动选择连接到 Ubuntu 或 Debian 发行版, 切换不同的开发环境。
我们这里使用单一发行版方式 Connect to WSL 就行

这个进度条是下载 server的进度,耐心等待,也可以点击蓝色字体,查看日志
[2025-08-18 15:43:27.708] Extension version: 0.99.0
[2025-08-18 15:43:27.708] L10N bundle: none
[2025-08-18 15:43:27.724] authorityHierarchy: wsl+ubantu-22.04
[2025-08-18 15:43:27.724] WSL extension activating for a local WSL instance
[2025-08-18 15:43:27.758] Download in background is enabled
[2025-08-18 15:43:27.759] Resolving wsl+ubantu-22.04, resolveAttempt: 1
[2025-08-18 15:43:27.761] WSL feature installed: true (dll path)
[2025-08-18 15:43:27.762] NodeExecServer run: C:\Windows\System32\wsl.exe --list --verbose
[2025-08-18 15:43:27.923] 4 distros found
[2025-08-18 15:43:27.925] Starting VS Code Server inside WSL (wsl2)
[2025-08-18 15:43:27.925] Windows build: 19045. Multi distro support: available. WSL path support: enabled
[2025-08-18 15:43:27.925] Scriptless setup: false
[2025-08-18 15:43:27.926] No shell environment set or found for current distro.
[2025-08-18 15:43:28.200] WSL daemon log file:
[2025-08-18 15:43:28.203] Probing if server is already installed: if [ -d ~/.vscode-server/bin/7adae6a56e34cb64d08899664b814cf620465925 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf 'alpine-'; fi; uname -m;
[2025-08-18 15:43:28.204] NodeExecServer run: C:\Windows\System32\wsl.exe -d ubantu-22.04 -e sh -c if [ -d ~/.vscode-server/bin/7adae6a56e34cb64d08899664b814cf620465925 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf 'alpine-'; fi; uname -m;
[2025-08-18 15:43:28.545] Probing result: x86_64
[2025-08-18 15:43:28.546] No server install found in WSL, needs linux-x64
[2025-08-18 15:43:28.546] Getting server from client side
[2025-08-18 15:43:28.547] Downloading VS Code Server stable - 7adae6a56e34cb64d08899664b814cf620465925 into C:\Users\djz\vscode-remote-wsl\stable\7adae6a56e34cb64d08899664b814cf620465925\vscode-server-stable-linux-x64.tar.gz.
[2025-08-18 15:43:30.899] Download checksum: 10fe710a4092311381eb43a60c5595585f6a1ea5bca632963e1ea649453913b0
[2025-08-18 15:43:57.766] New commit detected: 360a4e4fd251bfce169a4ddf857c7d25d1ad40da
[2025-08-18 15:43:57.766] No recently used WSL platforms found. Skipping download.
从日志来看,VS Code 连接 WSL 时因未找到已安装的 Server 而尝试下载,但后续因检测到新提交且无近期使用的 WSL 平台记录,跳过了下载,可以手动下载
在 VS Code 输出日志(Remote - WSL 面板)中,找到类似 https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable 的链接(比如日志里的 7adae6a56e34cb64d08899664b814cf620465925 对应版本)。
https://update.code.visualstudio.com/commit:7adae6a56e34cb64d08899664b814cf620465925/server-linux-x64/stable
把这个链接贴到 浏览器

在 wsl中创建如下 目录,注意 7adae6a56e34cb64d08899664b814cf620465925 是上边说的 commit_id
mkdir -p ~/.vscode-server/bin/7adae6a56e34cb64d08899664b814cf620465925/
将 vscode-server-linux-x64.tar.gz 拷贝到 目录,可以直接用win10的复制粘贴

去到路径下 tar -zxvf vscode-server-linux-x64.tar.gz

解压完了之后 重新打开 vscode


打开 对应的文件夹,这里我直接去到 dify api 目录下


点击 相信作者
3.3 尝试单步调试
3.3.0 安装python调试拓展
@category:debuggers Python

安静等待一会

安装完毕
3.3.1 关闭之前打开的 api服务

3.3.2 编辑 launch.json



{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/app.py",
"env": {
"FLASK_APP": "app.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "1"
},
"args": [
"run",
"--host=0.0.0.0",
"--port=5001"
],
"jinja": true
}
]
}

3.3.3 测试断点


打一个断点

登录

我们可以看到进入了断点

这个时候我们可以愉快的读代码了,往下可以结合 浏览器的network、源码和单步断点进行 源码阅读,方便对源码进行剖析了。
更多推荐


所有评论(0)