简介:面向具备一定编程基础、熟悉Git、Docker及Python的开发者,这是一份Windows系统下Dify Hackathon安装部署教程,系统讲解如何在Windows 10/11环境中从零搭建Dify开源大语言模型应用开发平台。作为一个开源平台,Dify适合快速构建人工智能应用,在Hackathon(黑客松)场景中可用于原型开发与调试。内容涵盖前置环境准备、克隆代码仓库、配置环境变量、使用docker-compose启动服务、初始化数据库及浏览器访问验证,并给出Docker启动失败、端口占用、服务无法访问等高频问题的排查思路。后续还补充了创建AI应用、集成自定义模型、参与Hackathon开发等建议。资源为单个Word(docx)文档,压缩包大小仅15KB,便于保存和快速查阅;全文以步骤命令、关键配置说明及验证方式为主,适合本地实践时对照操作。现已累计125人学习下载,适合需要快速搭建Dify开发环境并参加Hackathon的技术爱好者。
1. Windows下Dify Hackathon安装部署:先搞定环境再谈做应用
参加Windows环境下的Dify Hackathon,第一天最容易浪费在环境搭建上。Dify本身是开源LLM应用开发平台,后端核心是Flask服务,前端是Next.js,整体由Docker Compose编排起来;如果只把它当普通Python项目直接跑,忽略容器网络、环境变量和端口映射,后面会翻车翻得莫名其妙。这篇笔记按我在Windows上把Dify本地部署跑通的过程来写,覆盖Docker Desktop配置、源码拉取、环境变量改动、首次启动观测点,到Add模型和Hackathon现场排错,命令和参数都偏“可直接抄作业”的粒度。适合两类人:Hackathon现场临时装机的选手,以及想先在本机把Dify社区版跑熟再往服务器迁移的开发者。
2. 安装前的硬前置:Docker Desktop、Git和Python各自要满足什么条件
很多人以为装Dify等于装个Python包,实际上Dify依赖Postgres、Redis、Weaviate、Sandbox等一整套服务,单跑Flask进程根本起不来。Windows下的正确做法是依靠Docker Desktop来跑官方编排,Git负责把仓库按正确行尾拉到本地,Python则更多用于Hackathon阶段的扩展脚本和密钥生成。三者缺一不可,但坑也正好都藏在三者交界处。
2.1 Docker Desktop的WSL2后端:默认值可以但建议改内存
Windows上装Docker Desktop有两种后端:Hyper-V和WSL2。Dify容器一拉就是十来个,推荐直接选WSL2,因为WSL2启动快、内存回收比Hyper-V好,Dify社区版默认docker-compose文件也偏向Linux容器。Docker Desktop安装完,在Settings -> General里把“Use the WSL 2 based engine”勾上,再确认一下默认发行版是当前正在用的Ubuntu或Debian。
如果你机器内存只有16GB,劝你不要用默认值硬扛。Dify首次启动时,api、worker、web、plugin_daemon、weaviate几个容器会同时吃内存,尤其weaviate做向量检索时会把缓存顶得很高。可以通过%USERPROFILE%.wslconfig来限制WSL2的内存上限,文件不存在就新建:
# 放在 %USERPROFILE%\.wslconfig [wsl2] memory=6GB processors=4 swap=2GB localhostForwarding=truememory给6GB,是因为Dify整套容器稳定运行时大概吃3GB多,留出一点余量给编译和日志。processors给4核是一个保守值,Hackathon现场如果旁边还有人开着VS Code和浏览器,限制CPU可以避免整个系统卡死。swap设为2GB,避免容器内存瞬间冲高时直接把WSL2虚拟机杀掉。
改完这个文件,需要让WSL2重新加载配置。在PowerShell里执行wsl --shutdown,再重新打开Docker Desktop,等系统托盘里的鲸鱼图标不再转圈。之后用wsl -l -v看一眼状态,如果VERSION列显示2,就说明你当前用的是WSL2。这个步骤看起来玄学,但很多“docker compose up到一半被kill”其实就是WSL2内存上限没设好。
2.2 Git安装:把core.autocrlf设置为false再clone
Windows上Git默认有个“好心”行为:checkout时把仓库里的LF转成CRLF。这个行为对普通文档无所谓,对Dify容器镜像却是毒药。Dify的docker目录里有entrypoint.sh,api镜像里也有shell脚本,这些文件在Linux容器里要按LF执行。一旦被Windows转成CRLF,容器启动时会报/bin/sh^M: bad interpreter,网上一查全是玄学,其实是行尾符问题。
我一般会先配置Git全局参数再拉仓库,命令顺序放前面比较稳:
git config --global core.autocrlf false git config --global core.eol lf git config --global --get core.autocrlf把core.autocrlf设为false,表示checkout时不自动转换行尾;core.eol lf进一步要求工作区文件保持LF。最后git config --get是验证一下,如果输出为false,说明配置生效。注意,如果你已经用默认Git配置clone过Dify,就算现在改这个参数,坏文件也已经躺在工作区里了,最省事的后悔药是删掉整个目录重新clone一次。
还有个容易被忽略的点:Hackathon现场如果机器上装了多个Git版本,老版本对core.eol协议支持不完整。装Git的时候最好在“Checkout as-is, commit as-is”那一项上选第三项。这不是必须项,但它能保证后续git pull不会在更新Dify源码时又偷偷把关键文件转成CRLF。
2.3 端口占用确认:80/443的两种情况
Dify默认通过Nginx容器对外暴露80和443端口,浏览器访问http://localhost就能进。Windows上这两个端口最常见的意外是IIS或“系统进程”占用。你Docker容器明明显示Up,访问却跳到IIS欢迎页,这种情况通常不是Dify的问题,而是宿主机80端口根本没转发到Nginx容器。
在PowerShell里可以先查端口占用:
Get-NetTCPConnection -LocalPort 80,443 -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, State, OwningProcess这条命令会列出80和443上的监听进程,OwningProcess对应的PID再用Get-Process -Id <PID>查看是谁。如果看到的是System进程ID为4,那多半是HTTP.sys占住端口,改Dify端口比跟系统服务较劲省事得多。
端口调整在.env文件里做,后面第3章会详细讲。这里先记一个对应关系:
| 对外入口 | 默认端口 | .env中的变量 | 影响范围 |
|---|---|---|---|
| HTTP控制台 | 80 | EXPOSE_NGINX_PORT | 换后访问地址会变 |
| HTTPS控制台 | 443 | EXPOSE_NGINX_SSL_PORT | 证书相关配置 |
| API容器内部端口 | 5001 | 容器间通信用 | 一般不对外暴露 |
如果是在局域网里给队友访问,改成8080后还需要放行Windows防火墙,管理员PowerShell执行:
netsh advfirewall firewall add rule name="Dify Web" dir=in action=allow protocol=TCP localport=8080这条命令的localport=8080要和.env里的EXPOSE_NGINX_PORT保持一致,否则Docker转发到了8080,防火墙却只放行80,队友照样连不上。Hackathon现场如果大家都用同一台机器做演示,这一步直接决定别人能否访问你的应用。
3. 拉取Dify代码与配置环境变量:clone、.env、compose.yaml三件事
前置环境确定后,下一步是把Dify仓库拿到本地、复制环境变量模板、确认compose文件位置。很多教程把这三步混在一句话里,实际上每一步都可能带出不同故障特征:clone阶段出换行符问题,.env阶段出密钥和端口问题,compose阶段出命令不存在问题。分开处理会好排查很多。
3.1 clone到本地:为什么换行符会破坏容器启动
在Windows Terminal里,进入你要放工程的盘符,比如D盘根目录,然后执行clone:
git clone <Dify官方仓库地址> D:\dify如果你不想记具体地址,也可以到Dify官网或GitHub页面复制仓库地址。这里故意不写死一串URL,因为不同参赛场地方提供的镜像仓库地址不一定相同,Hackathon现场有时会要求内部镜像加速,直接用你拿到的地址替换即可。
如果网络状况不好,可以加浅克隆参数:
git clone --depth 1 --branch <版本标签> <Dify官方仓库地址> D:\dify--depth 1表示只拉最近一次提交,能大幅减少传输量,但代价是你之后想切换其他版本标签时会比较麻烦。--branch后面填具体标签,比如1.10.x这类社区版标签,按你实际拿到的通知来填。没有明确版本要求时可以不写branch,直接拉默认分支。
clone完成后,进到目录里看一眼有没有docker这个子目录:
Set-Location D:\dify Get-ChildItemDify的docker编排文件是放在docker子目录里的,根目录下的.env.example未必是最新版。如果你在根目录找不到.env.example,多半是版本目录结构变了,这时候认准docker目录。我见过不少人在根目录反复执行docker compose,然后提示找不到compose文件,其实是走错了目录。
3.2 .env关键参数:EXPOSE_NGINX_PORT、SECRET_KEY与VERSION
Dify的配置入口是docker/.env.example,进入docker目录后把它复制成.env:
Set-Location D:\dify\docker Copy-Item .env.example .env.env是Dify所有容器读取环境变量的源头,Nginx、api、web、worker都会从这里取值。复制完不要直接启动,先改三个最关键的参数。
第一个是SECRET_KEY,它用于Flask签名Cookie和CSRF保护。.env.example里通常给了一个示例值,如果保持默认,所有按同样教程搭建的人都会得到相同密钥,别人构造的Cookie可以直接冒充你的管理员身份。生成一个新密钥很简单,Windows下用Python:
python -c "import secrets; print(secrets.token_hex(32))"如果你的机器上python命令被Windows Store的占位符拦截,就用py -3 -c "import secrets; print(secrets.token_hex(32))"。把输出的一长串hex复制到.env的SECRET_KEY=后面,值里不要加引号、不要加空格,因为compose解析时会把空格也当成值的一部分。
第二个要改的是对外端口。如果80端口被系统服务占用,直接把EXPOSE_NGINX_PORT改成8080,EXPOSE_NGINX_SSL_PORT改成8443。注意,只改这两个变量还不算完,NGINX_PORT和NGINX_SSL_PORT是容器内部的监听端口,一般保持默认不动;对外端口变量名带EXPOSE前缀,才是宿主机上真正监听的端口。
第三个值是数据库和Redis密码。.env.example里默认密码是可预测的,参赛现场如果整个网络环境里有人扫描,默认密码很容易被测出来。把POSTGRES_PASSWORD、DB_PASSWORD、REDIS_PASSWORD统一改成一串新的强密码,并且三个地方的密码要互相匹配。这里给出我常用的参数表:
| 变量名 | 默认值 | 建议改法 | 影响 |
|---|---|---|---|
| SECRET_KEY | 固定示例串 | 用secrets生成hex | 登录态安全 |
| EXPOSE_NGINX_PORT | 80 | 改成8080或随机高位端口 | 浏览器访问入口 |
| EXPOSE_NGINX_SSL_PORT | 443 | 改成8443 | HTTPS入口 |
| POSTGRES_PASSWORD | 默认值 | 改成32位随机串 | 数据库连接 |
| DB_PASSWORD | 默认值 | 与POSTGRES_PASSWORD保持一致 | api连库 |
| REDIS_PASSWORD | 默认值 | 改成随机串 | redis连接 |
3.3 compose 文件位置:Windows 新旧命令差别的处理
Dify仓库里的编排文件是docker/docker-compose.yaml,不是放在根目录。确认路径后,先做一次配置校验,再真正启动:
docker compose --env-file .env -p dify config --quiet这条命令里的--env-file .env指定环境变量文件,-p dify把项目名固定为dify,config --quiet只校验配置不创建容器。如果配置里有变量没被替换,这里会直接报错,错误信息会比启动时更直观。
Windows上还残留着两个相似命令:docker compose和docker-compose。前者是Docker官方v2插件,随Docker Desktop默认安装;后者是旧版独立二进制,很多老教程还在用。2024年以后的新环境里,Docker Desktop官方安装包已经不带docker-compose独立命令了,所以你执行docker-compose大概率提示“无法识别”。如果你以前装过独立的docker-compose,版本又是1.x,它在解析新版compose文件时可能不认depends_on的某些写法。
判断当前命令是否可用:
docker compose version如果输出类似Docker Compose version v2.x.x,说明路径正确。后面所有启动命令都用docker compose,不要混用。为了减少现场输入错误,我习惯把项目名固定下来:
$env:COMPOSE_PROJECT_NAME="dify" docker compose --env-file .env up -dPowerShell里用$env:给当前会话设置COMPOSE_PROJECT_NAME,之后不带-p dify也能维持同一套容器前缀。如果不开新终端,这个变量只在当前会话有效,不会污染全局。容器前缀统一后,后续查日志和找volume都会方便很多。
4. 执行docker compose up -d:容器启动顺序与第一次初始化的观测点
配置没问题,接下来就是拉镜像和启动。这一步最大的风险不是命令写错,而是“不知道当前进度到哪了”。Dify首次启动需要拉多个镜像,还要做数据库迁移,界面看起来像卡死,实际容器内部正在忙。掌握启动命令、日志观测和初始化完成后三个状态,基本就能判断系统健不健康。
4.1 启动命令与docker compose ps状态
进入D:\dify\docker目录,执行正式启动:
Set-Location D:\dify\docker docker compose --env-file .env -p dify up -d-d表示后台运行,pull镜像和创建容器的过程不会一直刷屏。第一次执行时,终端会长时间停在“Pulling”状态,这是正常的,Dify全家桶包含api、worker、web、nginx、postgres、redis、weaviate、sandbox、ssrf_proxy、plugin_daemon等十来个服务,镜像总量比较大。如果中途网络断开,重新执行同样命令即可,Docker会续传已下载的层。
启动完成后查看容器状态:
docker compose --env-file .env -p dify ps -a正常状态下,大部分容器Status列应该显示Up,尤其是api、worker、web、nginx这四类关键服务。如果你看到某个容器状态是Restarting,说明它启动后崩溃了,需要单独看日志。-a参数会把已停止的容器也列出来,方便看到哪些服务根本没起来。
另外,docker compose ps输出的PORTS列只显示宿主机暴露的端口。如果.env里把对外端口改成了8080,这里会显示0.0.0.0:8080->80/tcp,看到这个映射关系就说明Nginx端口转发正常。
4.2 看日志:等待api与plugin_daemon完成的几次“长时间无输出”
容器全部起来不等于服务全部就绪。Dify里最容易给人“卡死”错觉的是api容器和worker容器。首次启动时api要等数据库就绪,还要执行数据库迁移,日志前几十行常常只有等待提示:
docker compose -p dify logs -f api如果日志滚动到Waiting for database connection就停下来,不要急着Ctrl+C,Give它一两分钟。Postgres首次初始化需要建库建表,api容器这时候是在轮询数据库。看到Database connection established后,日志会累出新内容,说明数据库链路打通。
然后是plugin_daemon。这个服务负责模型供应商插件加载,第一次启动时会同步插件元数据,输出密集程度远低于api。很多Hackathon选手在这一步误判为死机,直接重启Docker Desktop,结果插件没加载完,后面接入模型时反复报错。
另一个观测点是worker容器。它负责异步任务,比如知识库索引和文档解析。如果worker没起来,你在网页里上传文档到知识库,任务会一直堆积在“处理中”。查看worker日志:
docker compose -p dify logs --tail=50 worker--tail=50只显示最后50行,适合快速判断是“正在运行”还是“启动失败”。看到Connected to redis之类的日志,说明worker和redis之间通讯正常;如果报Redis连接被拒绝,优先检查.env里的REDIS_PASSWORD是否和compose里Postgres等服务的密码设置一致。
4.3 浏览器初始化管理员账号与默认HTTP端口
容器日志稳定后,打开浏览器访问http://localhost。如果你改过EXPOSE_NGINX_PORT,就访问http://localhost:8080。第一次访问会进入初始化向导,需要创建一个管理员账号,填写邮箱、姓名、密码。这里容易有个误解:邮箱不是用来收验证邮件的,只要格式合法就能过。
管理员账号创建完,页面会跳到Dify控制台主界面。到这一步,“安装部署”已经成功了。接下来先别急着写工作流,先干两件事:一是确认右上角能看到你的头像,说明登录态写入成功;二是进入“设置 -> 模型供应商”,随便添加一个模型试试,因为Hackathon的核心是把模型跑通,不是只看页面。
如果你希望验证API入口是否正常,可以在浏览器打开http://localhost:8080/health,会返回一个正常状态文本。这个接口走Nginx转发到api容器,能明确告诉你整条网络链路是不是通着的。返回异常时,再分别查nginx和api两个容器日志,前后端的问题就能分隔开。
5. Windows下安装避坑:五个让Dify“翻车”的常见问题
以下是实际在Windows上装Dify最容易遇到的五个坑。它们很多看起来像“Docker坏了”“镜像有问题”,最后定位下来全是Windows环境细节。整理成“现象 -> 原因 -> 解决”的结构,方便你现场照着排查。
5.1 现象:WSL2内存占满,docker compose up到一半被kill
现象是执行docker compose up -d后,终端突然跳出类似Killed的报错,Docker Desktop整个变灰,再打开容器大量消失。原因不是Dify镜像占内存夸张,而是WSL2虚拟机的默认内存上限会跟宿主机抢资源,拉镜像和容器间通信同时发生时,内存触顶。解决方法是写.wslconfig限制内存,然后执行wsl --shutdown,重新打开Docker Desktop。等Docker引擎启动完再重新docker compose up -d。这一步的关键是:改完.wslconfig必须关闭全部WSL会话,包括Docker Desktop,否则配置不生效。
5.2 现象:entrypoint.sh报/bin/sh^M: bad interpreter
这种现象在Windows下clone Dify后特别明显:api容器或worker容器启动即崩溃,日志里的错误指向shell脚本解释失败。原因是之前说的Git行尾转换,仓库里的LF被Windows Git转成CRLF。解决方式是先执行git config --global core.autocrlf false,然后把已经clone到本地的Dify目录整个删掉,重新clone。不要试图手动改文件行尾,因为Dify内部脚本不止一两个,漏改后续还是会报错。这是血泪经验,配置Git参数必须在clone之前,之后再做都是给现场添麻烦。
5.3 现象:Docker容器提示找不到挂载盘或目录为空
现象是容器能起来,但打开Dify页面后上传的文件丢失,或者容器日志里出现类似share has been granted but path not found。原因是Dify目录被放在了OneDrive、Dropbox这类云同步目录里,云盘会锁文件,Docker Desktop的共享机制解析不了这种路径。解决方法是把整个Dify工程挪到本地磁盘,比如C:\dify或D:\dify,不要在用户目录下的同步文件夹里安装。另外,如果目录放在D盘而Docker Desktop没有授权共享D盘,也会出现同样问题,需要到Docker Desktop的Settings -> Resources -> File Sharing里把对应盘符勾上。
5.4 现象:Windows重启后Dify所有页面打不开
Windows重启后Docker Desktop不会自己恢复所有容器,特别是WSL2模式下,很多容器的状态会变成Exited。现象是浏览器访问http://localhost直接拒绝连接,但Docker Desktop右下角图标看着正常。原因是Docker Desktop开机后只启动引擎,不会主动拉起你手动创建的compose项目。解决方法是重新执行启动命令:
Set-Location D:\dify\docker docker compose --env-file .env -p dify up -d如果你想偷懒,可以在Windows任务计划程序里加一个开机脚本,但Hackathon现场不建议这么做,因为比赛环境可能随时重启网络,手动拉起反而更容易控制启动顺序。
5.5 现象:添加模型供应商时报“an error occurred during credentials validation”
这是接入外部模型时最容易遇到的拦路虎。现象是在Dify控制台填写模型API Key后点击保存,界面弹出An error occurred during credentials validation。原因有两个方向:一是Dify的plugin_daemon服务要发外部请求验证Key,Windows容器网络里对这类外部请求有限制,经常是SSL证书检查失败;二是host.docker.internal在Windows和Linux容器之间的解析不够稳定,导致自建模型的验证请求到达不了宿主机。
解决时分两步走。先查看plugin_daemon的日志:
docker compose -p dify logs --tail=100 plugin_daemon如果日志里有SSL或证书相关报错,说明验证链路被网络策略挡住,优先换用本机可直连的模型,比如用Ollama搭本地模型,在供应商设置里把API基础地址填成http://host.docker.internal:11434。这个地址专门用于Windows容器访问宿主机服务,不要填localhost,因为容器内的localhost指向容器自己。如果是外部模型,确认Key本身有效且服务没欠费,不要把密钥填错。这类问题不是Docker玄学,本质上是验证请求没到达该到的地方。
6. Hackathon里的落地技巧:用环境变量迁移与固定容器版本
6.1 固定Dify镜像版本,别让默认标签坑了后续
Hackathon现场最怕“昨天还能用,今天容器重启后版本变了”。Dify的docker-compose里部分镜像可能没有锁死具体版本,默认拉取标签会随时间漂移。比赛前我会先查看本地镜像标签:
docker compose --env-file .env -p dify config | Select-String "image:"确认当前实际使用的镜像标签后,直接编辑docker/docker-compose.yaml或对应的.env变量,把image:字段改成固定标签。这样能保证另一台电脑复现时,拉到的镜像和你是同一套,避免api和web版本不匹配导致页面登录后白屏。Hackathon结束时把这份改过的compose文件和.env模板一起提交,比口头交代步骤可靠得多。
6.2 用docker compose config做交付前验证
我每次准备提交前,都会强制走一遍同样的检查命令:
docker compose --env-file .env -p dify config --quiet docker compose --env-file .env -p dify ps --format json第一条命令验证环境变量有没有缺漏,第二条把容器运行状态输出为结构化JSON,方便快速数出到底哪些服务没起来。然后浏览器访问页面,随机走一遍“创建应用 -> 添加模型 -> 对话”的流程。只有这几步全通,我才会把部署过程写进参赛文档。从那以后,我在Windows上部署Dify都强制先改.env、再跑config校验、最后才启动容器,这套顺序帮我省掉了很多次现场救火。希望帮到你。
本文还有配套的精品资源,点击获取