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、源码和单步断点进行 源码阅读,方便对源码进行剖析了。

更多推荐