錯(cuò)排查:從環(huán)境配置到運(yùn)行實(shí)戰(zhàn)全解析)
如果你正在用 Docker 部署 Dify 這個(gè)開(kāi)源 AI 智能體平臺(tái)大概率已經(jīng)被一堆報(bào)錯(cuò)磨得沒(méi)了脾氣。docker compose up -d看起來(lái)是個(gè)一句話的事但真正跑起來(lái)虛擬化檢測(cè)失敗、Docker API 連不上、鏡像憑據(jù)校驗(yàn)報(bào)錯(cuò)、SSL 證書(shū)不匹配、登錄被鎖……每一個(gè)都能讓你白天裝環(huán)境、晚上查日志。這篇文章就是把我自己從 Windows Docker Desktop 到 CentOS 7 服務(wù)器上部署 Dify 的過(guò)程中踩過(guò)的坑和排查思路完整梳理一遍按“Docker 環(huán)境 → 鏡像拉取 → 編排啟動(dòng) → 應(yīng)用運(yùn)行”四個(gè)階段拆開(kāi)講無(wú)論你是第一次碰 Docker 的新手還是已經(jīng)被 Dify 折騰到懷疑人生的老手應(yīng)該都能從中找到對(duì)應(yīng)的解法。1. 部署前先想清楚Dify 為什么綁定 Docker以及兩條部署路線的坑先說(shuō)一個(gè)現(xiàn)象Dify 官方文檔、GitHub README、教程視頻幾乎全都讓你用 Docker Compose 一鍵部署幾乎沒(méi)人推薦裸機(jī)安裝。這不是因?yàn)楣俜酵祽卸?Dify 的架構(gòu)天然適合容器化理解了這一點(diǎn)后面遇到報(bào)錯(cuò)才知道該往哪個(gè)方向查。1.1 Dify 的組件結(jié)構(gòu)決定了它離不開(kāi) ComposeDify 一個(gè)完整實(shí)例跑起來(lái)至少包含這么幾個(gè)容器nginx反向代理和靜態(tài)資源、api后端服務(wù)、worker異步任務(wù)隊(duì)列比如知識(shí)庫(kù)文檔切片和索引、web前端頁(yè)面、dbPostgreSQL、redis緩存和會(huì)話、sandbox代碼執(zhí)行沙箱、ssrf_proxy請(qǐng)求代理防 SSRF、還有向量數(shù)據(jù)庫(kù)weaviatev1.x 默認(rèn)自帶。這九個(gè)服務(wù)之間有固定的啟動(dòng)順序、共享網(wǎng)絡(luò)、依賴數(shù)據(jù)庫(kù)初始化如果手動(dòng)一個(gè)個(gè)裝光是把 PostgreSQL、Redis 和向量庫(kù)配置到互相認(rèn)得對(duì)方就夠你折騰一天的。Compose 的價(jià)值就是把這些服務(wù)編排到一起一次性拉起并且通過(guò)環(huán)境變量和內(nèi)部網(wǎng)絡(luò)自動(dòng)完成服務(wù)間通信。所以“Dify 部署”本質(zhì)上是“Docker 部署能力”的驗(yàn)收Docker 環(huán)境本身不穩(wěn)Dify 就不可能穩(wěn)。1.2 Windows 和 Linux 兩條路線各自的坑完全不一樣部署 DifyWindows Docker Desktop和Linux 服務(wù)器 Docker Engine是兩條完全不同的路線報(bào)錯(cuò)的表現(xiàn)形式也千差萬(wàn)別。Windows 上的核心問(wèn)題集中在Docker Desktop 本身能不能跑起來(lái)。新版 Docker Desktop 基于 WSL2如果系統(tǒng)虛擬化沒(méi)開(kāi)、WSL 內(nèi)核沒(méi)更新、Hyper-V 組件缺失Docker Desktop 就直接罷工出現(xiàn)virtualization support not detected或者failed to connect to the docker api at npipe:////./pipe/dockerdesktoplinuxen這種經(jīng)典報(bào)錯(cuò)。Linux 服務(wù)器比如常見(jiàn)的 CentOS 7的坑則在Docker CE 安裝源、內(nèi)核兼容性、防火墻沖突上。CentOS 7 內(nèi)核 3.10 對(duì) Docker 和 iptables 的支持都比較老容易遇到iptables: No chain/target/match by that name這基本是 firewalld 和 docker 的 NAT 規(guī)則打架。所以排障的第一步應(yīng)該先確認(rèn)自己走的是哪條路別拿 Windows 的方案去套服務(wù)器也別拿服務(wù)器的命令去處理 Docker Desktop否則永遠(yuǎn)找不到真正的根因。2. Docker 環(huán)境本身的報(bào)錯(cuò)虛擬化、API 連接、網(wǎng)絡(luò)三座大山這一節(jié)處理的都是“Docker 還沒(méi)開(kāi)始拉鏡像就已經(jīng)出問(wèn)題”的情況。我按實(shí)際遇到頻率從高到低來(lái)排序這些都是熱搜詞里出現(xiàn)次數(shù)最多的幾個(gè)報(bào)錯(cuò)。2.1 Docker Desktop 打不開(kāi)提示 virtualization support not detected這個(gè)報(bào)錯(cuò)的完整文本一般是virtualization support not detected docker desktop failed to start because v...意思是 Docker Desktop 檢測(cè)不到虛擬化支持拒絕啟動(dòng)。原因基本就三個(gè)BIOS/UEFI 沒(méi)開(kāi)啟硬件虛擬化。Intel 平臺(tái)是 VT-xAMD 平臺(tái)是 SVM很多品牌機(jī)出廠默認(rèn)關(guān)閉。Windows 的虛擬機(jī)相關(guān)功能沒(méi)啟用。新版 Docker Desktop 依賴 WSL2而 WSL2 需要“虛擬機(jī)平臺(tái)”和“適用于 Linux 的 Windows 子系統(tǒng)”這兩個(gè) Windows 功能。舊版 Hyper-V 和 WSL2 沖突導(dǎo)致 hypervisor 層沒(méi)有正確加載。排查步驟我建議按這個(gè)順序來(lái)打開(kāi)任務(wù)管理器 → 性能 → CPU看右下角“虛擬化”是否顯示“已啟用”。如果是“已禁用”先進(jìn) BIOS 找Intel Virtualization Technology或SVM Mode開(kāi)啟后保存重啟。如果已經(jīng)啟用再去“啟用或關(guān)閉 Windows 功能”里把Hyper-V、虛擬機(jī)平臺(tái)、適用于 Linux 的 Windows 子系統(tǒng)三個(gè)勾上。重啟后打開(kāi)終端執(zhí)行wsl --status如果 WSL 內(nèi)核版本是老的去官網(wǎng)下載最新的 WSL2 內(nèi)核更新包裝一遍。最后再打開(kāi) Docker Desktop到 Settings → Resources → WSL Integration 里確認(rèn)你的發(fā)行版比如 Ubuntu被勾選。注意如果電腦上裝過(guò)舊版 Docker Toolbox它依賴 VirtualBox和 Docker Desktop 的 Hyper-V/WSL2 后端會(huì)起沖突。建議徹底卸載 Toolbox 和 VirtualBox 再裝 Docker Desktop。我實(shí)測(cè)中最容易忽略的是bcdedit /set hypervisorlaunchtype auto這個(gè)命令。如果你之前手動(dòng)關(guān)過(guò) hypervisor即使 BIOS 里虛擬化開(kāi)著Docker Desktop 一樣起不來(lái)。用管理員權(quán)限跑一下這條命令再重啟很多“明明都開(kāi)了卻還是報(bào)錯(cuò)”的情況能直接解決。2.2 Windows 下 failed to connect to the docker api at npipe 報(bào)錯(cuò)完整報(bào)錯(cuò)是failed to connect to the docker api at npipe:////./pipe/dockerdesktoplinuxen這個(gè)“npipe”是 Windows 上命名管道相當(dāng)于 Linux 的/var/run/docker.sock。報(bào)這個(gè)錯(cuò)本質(zhì)是 Docker CLI 想連 Docker Engine但 Engine 沒(méi)在監(jiān)聽(tīng)。最容易踩的坑是Docker Desktop 圖標(biāo)顯示在托盤(pán)里你以為它啟動(dòng)了其實(shí) Engine 還在初始化尤其是第一次啟動(dòng)或者剛更新完。此時(shí)docker version就會(huì)報(bào)連接不上 API。解決順序右鍵托盤(pán) Docker Desktop 圖標(biāo)選 Restart等鯨魚(yú)圖標(biāo)變成穩(wěn)定狀態(tài)不再轉(zhuǎn)圈。重啟還不行就在終端執(zhí)行wsl --shutdown把整個(gè) WSL 子系統(tǒng)關(guān)掉再重新打開(kāi) Docker Desktop。查看 WSL 里是否有殘留的 docker-desktop 發(fā)行版卡死wsl -l -v看一眼狀態(tài)。如果顯示 Stopped在 Docker Desktop 里 Settings → Troubleshoot 點(diǎn) Restart。注意C 盤(pán)剩余空間。Docker Desktop 的 WSL 虛擬磁盤(pán)文件ext4.vhdx會(huì)占用大量空間如果 C 盤(pán)滿了Engine 同樣啟動(dòng)不了。清理磁盤(pán)或用diskpart壓縮 vhdx 后再試。這個(gè)報(bào)錯(cuò)本質(zhì)上就是“CLI 和 Engine 斷了”90% 的情況是 Engine 沒(méi)起來(lái)不是配置錯(cuò)。我在幫朋友排查時(shí)發(fā)現(xiàn)很多人的問(wèn)題出在 Windows 更新后 WSL 被重置導(dǎo)致 Docker Desktop 里集成失效。重新勾選 WSL Integration 并重啟立刻就好了。2.3 Docker 網(wǎng)絡(luò)不通容器通、外部不通還是 DNS 解析失敗Docker 的網(wǎng)絡(luò)問(wèn)題在部署 Dify 時(shí)特別煩因?yàn)?Dify 有九個(gè)容器要互相通信任何一環(huán)網(wǎng)絡(luò)亂掉前端界面是起來(lái)了但登錄后 API 全部報(bào)錯(cuò)。最常見(jiàn)的兩類(lèi)網(wǎng)絡(luò)癥狀第一類(lèi)容器相互 ping 不通docker compose ps 顯示服務(wù)是 running 但功能異常。這多半是 Docker 默認(rèn)的bridge網(wǎng)橋被搞亂了。你可以在daemon.json里自定義網(wǎng)段通過(guò)設(shè)置bip參數(shù)避開(kāi)公司內(nèi)網(wǎng)或路由器網(wǎng)段避免 Docker 默認(rèn)網(wǎng)段 172.17.0.0 和其他設(shè)備沖突。改完daemon.json后記得systemctl restart docker。第二類(lèi)容器能啟動(dòng)但沒(méi)有外網(wǎng)拉不了模型或者知識(shí)庫(kù)外部請(qǐng)求超時(shí)。這通常是 DNS 問(wèn)題。Docker 默認(rèn)會(huì)用宿主機(jī)的 DNS但某些環(huán)境尤其是公司內(nèi)網(wǎng)或者某些云主機(jī)自身 DNS 就解析不了外網(wǎng)。我在daemon.json里加了這段來(lái)解決{ dns: [223.5.5.5, 119.29.29.29] }然后重啟 docker。原理是讓容器直接用公共 DNS 做解析。改完用docker exec container ping baidu.com驗(yàn)證。還有一類(lèi)隱蔽問(wèn)題是防火墻的 iptables 規(guī)則被重置。Docker 安裝時(shí)會(huì)往 iptables 里寫(xiě) NAT 和 FORWARD 規(guī)則如果后來(lái)你手動(dòng)執(zhí)行過(guò)iptables -F或者裝了防火墻管理工具規(guī)則會(huì)被清掉容器就徹底沒(méi)網(wǎng)絡(luò)了。此時(shí)最快的方式是systemctl restart docker讓 Docker 重新寫(xiě)入規(guī)則。經(jīng)驗(yàn)部署 Dify 前先檢查宿主機(jī)能不能ping通外網(wǎng)再檢查docker run --rm alpine ping 8.8.8.8能不能通。把“宿主機(jī)網(wǎng)絡(luò)”和“容器網(wǎng)絡(luò)”分開(kāi)測(cè)試能快速定位到到底斷在哪一層。3. 安裝 Dify 過(guò)程的核心報(bào)錯(cuò)鏡像拉取、憑據(jù)校驗(yàn)、端口沖突Docker 環(huán)境終于跑起來(lái)了接下來(lái)是git cloneDify 倉(cāng)庫(kù)并啟動(dòng)。這個(gè)階段的問(wèn)題集中在鏡像拉取、憑據(jù)驗(yàn)證、端口占用這三個(gè)地方。3.1 完整安裝 Dify 的正確操作序列先給一個(gè)標(biāo)準(zhǔn)的安裝流程后面的報(bào)錯(cuò)都是基于這個(gè)流程展開(kāi)的。git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env docker compose up -d這是最干凈的三步。注意順序不能亂尤其是先cp .env.example .env再 up因?yàn)?Dify 的 Compose 文件大量引用了.env里的變量跳過(guò)就會(huì)報(bào)variable is not set。啟動(dòng)后看狀態(tài)docker compose ps看到一堆容器都是running (healthy)才算成功。如果某個(gè)容器狀態(tài)是starting或者unhealthy用docker compose logs -f service看具體日志。3.2 an error occurred during credentials validation多半是登錄憑據(jù)問(wèn)題這個(gè)報(bào)錯(cuò)在網(wǎng)絡(luò)上的熱度很高。當(dāng)你執(zhí)行docker compose pull拉鏡像時(shí)報(bào)an error occurred during credentials validation基本就是在拉取某個(gè)鏡像時(shí)Docker 嘗試用你本機(jī)保存的 registry 登錄憑據(jù)去認(rèn)證但憑據(jù)已經(jīng)失效或者不匹配。排查方式docker logout docker login先登出再重新登錄注意登錄的 registry 地址要對(duì)。如果你用的是公共 Docker Hubdocker login直接輸用戶名密碼即可如果你在daemon.json里配置了第三方鏡像加速源有些加速源要求額外的認(rèn)證信息那就要檢查你的憑據(jù)是哪個(gè) registry 的。還有一種隱蔽情況是~/.docker/config.jsonWindows 是%USERPROFILE%\.docker\config.json里的auths字段殘留了舊的認(rèn)證信息。手動(dòng)打開(kāi)這個(gè)文件把對(duì)應(yīng) registry 的 auth 刪除再重新拉。Docker 會(huì)優(yōu)先讀這個(gè)文件里的 token哪怕 Docker Hub 本身登錄正常舊 token 也會(huì)干擾。3.3 docker pull 鏡像一直超時(shí)或者卡在 waiting 狀態(tài)第一次部署 Dify要拉 nginx、postgres、redis、weaviate 等接近 2GB 的鏡像。如果網(wǎng)絡(luò)條件不夠理想經(jīng)常出現(xiàn)pull access denied、timeout或者卡在waiting。這里最有效的調(diào)整是配置daemon.json的 mirror 加速地址。在/etc/docker/daemon.jsonWindows 在 Docker Desktop Settings → Docker Engine加字段{ registry-mirrors: [https://你的加速地址] }改完執(zhí)行systemctl restart dockerWindows 上重啟 Docker Desktop。配置好之后docker pull大鏡像的速度提升非常明顯這是國(guó)內(nèi) Docker 用戶部署 Dify 的剛需配置。另一個(gè)注意點(diǎn)是磁盤(pán)空間。Dify 所有鏡像 運(yùn)行后的 volume 數(shù)據(jù)輕松超過(guò) 10GB。拉鏡像時(shí)報(bào)no space left on device就說(shuō)明/var/lib/docker所在分區(qū)滿了。檢查方式df -h docker system df清理方式可以用docker system prune -a刪掉所有無(wú)用鏡像和構(gòu)建緩存。注意這個(gè)命令會(huì)連帶刪除停止的容器如果之前有數(shù)據(jù)容器需要用docker volume保住數(shù)據(jù)。3.4 端口沖突一啟動(dòng) Dify 就把宿主機(jī) nginx 帶崩了Dify 默認(rèn)把 nginx 映射在宿主機(jī)的 80 端口上。如果你宿主機(jī)已經(jīng)跑了 nginx、Apache、或者某寶一鍵裝的環(huán)境docker compose up -d會(huì)直接報(bào)port is already allocated。解法是修改.env文件EXPOSE_NGINX_PORT18080 EXPOSE_API_PORT18081把這些變量改成 18080 等不沖突的端口然后重新docker compose up -d。訪問(wèn)地址就會(huì)從http://localhost變成http://localhost:18080。注意改完.env后一定要在docker目錄下重新執(zhí)行docker compose up -d不能只改文件不重啟Compose 只有在重新 up 時(shí)才會(huì)讀取新的環(huán)境變量。3.5 CentOS 7 上安裝 docker 的額外“天坑”如果你在 CentOS 7 上部署除了上面的通用問(wèn)題還會(huì)遇到幾個(gè)特有的大坑。第一個(gè)是Docker CE 的安裝源。CentOS 7 默認(rèn) yum 源里沒(méi)有 docker-ce只有老的 docker 包。必須先用官方源或國(guó)內(nèi)鏡像源添加 docker-ce 倉(cāng)庫(kù)然后yum install docker-ce否則裝出來(lái)的不是你要的版本。第二個(gè)是內(nèi)核兼容性。CentOS 7 默認(rèn)內(nèi)核 3.10Docker 新版對(duì)overlay2存儲(chǔ)驅(qū)動(dòng)的支持要看內(nèi)核模塊。如果啟動(dòng) docker 時(shí)報(bào)overlay2: not supported可以把存儲(chǔ)驅(qū)動(dòng)改成vfs{ storage-driver: vfs }這會(huì)犧牲一點(diǎn)性能但能保證啟動(dòng)成功。第三個(gè)是firewalld 和 iptables 沖突報(bào)錯(cuò)iptables: No chain/target/match by that name。原因很典型Docker 啟動(dòng)時(shí)想往 iptables 里寫(xiě)規(guī)則但 firewalld 也在管理 iptables二者互相覆蓋。最直接的辦法是把 firewalld 停掉systemctl stop firewalld systemctl disable firewalld再重啟 docker。在干凈的 iptables 環(huán)境下Docker 能穩(wěn)定創(chuàng)建自己的 NAT 鏈。4. Dify 啟動(dòng)后的運(yùn)行期報(bào)錯(cuò)SSL 錯(cuò)誤、登錄鎖、多租戶和工作流問(wèn)題鏡像拉下來(lái)了容器全部起來(lái)了你以為就結(jié)束了NoDify 運(yùn)行期還有一批“軟性”報(bào)錯(cuò)這些報(bào)錯(cuò)的表現(xiàn)形式往往很迷惑讓人以為代碼有問(wèn)題實(shí)際全是環(huán)境和配置的問(wèn)題。4.1 訪問(wèn) Dify 時(shí)報(bào) SSL 錯(cuò)誤或者一直跳 HTTPSDify 默認(rèn)是 HTTP 訪問(wèn)的但很多用戶用反代或者某些瀏覽器插件強(qiáng)制 HTTPS 后訪問(wèn)http://localhost會(huì)出現(xiàn)證書(shū)錯(cuò)誤或者界面加載一半報(bào) SSL 相關(guān)錯(cuò)誤。首先要明確如果你沒(méi)有配置 HTTPS 證書(shū)那就用 http 訪問(wèn)不要開(kāi) https。訪問(wèn)地址寫(xiě)成http://服務(wù)器IP:端口不要把瀏覽器自動(dòng)補(bǔ)全的https://留下。如果你確實(shí)需要 HTTPS比如做微信公眾號(hào)回調(diào)、小程序開(kāi)發(fā)平臺(tái)要求必須 https那就把 Dify 放到 nginx 反代后面用正規(guī)渠道簽證書(shū)。有幾個(gè)注意點(diǎn)反代服務(wù)器會(huì)繼承 Dify Web 容器的實(shí)際響應(yīng)需要在反代配置里加上proxy_set_header X-Forwarded-Proto $scheme;否則 Dify 自身不知道用戶是通過(guò) HTTPS 訪問(wèn)的回調(diào)地址還是會(huì)生成 http 鏈接。如果你之前用 IP 訪問(wèn)過(guò)Dify 可能會(huì)在瀏覽器里緩存了 HTTP 的 service worker導(dǎo)致 HTTPS 下控制臺(tái)報(bào)錯(cuò)。解決方式是在瀏覽器設(shè)置里清除該站點(diǎn)數(shù)據(jù)不要只是刷新頁(yè)面。如果日志里出現(xiàn)SSL: WRONG_VERSION_NUMBER或類(lèi)似錯(cuò)誤說(shuō)明客戶端以 HTTPS 協(xié)議去連一個(gè) HTTP 端口端口對(duì)不上。檢查反代配置里的 upstream 端口是否指向了 Dify 的 nginx 容器映射端口。4.2 登錄報(bào)錯(cuò) too many incorrect password attempts. please try again later.這個(gè)報(bào)錯(cuò)我在社區(qū)里見(jiàn)到的頻率極高而且非常容易誤判。它出現(xiàn)在你連續(xù)輸錯(cuò)幾次密碼后Dify 會(huì)把當(dāng)前登錄 IP 鎖定一段時(shí)間提示too many incorrect password attempts. please try again later.。這個(gè)是一個(gè)安全機(jī)制不是 bug。Dify 默認(rèn)對(duì)單 IP 的失敗登錄次數(shù)做了限制鎖定期大概是幾分鐘到一小時(shí)。處理方式等鎖定期過(guò)去再試期間不要瘋狂點(diǎn)登錄否則鎖定期會(huì)刷新。如果等不及可以通過(guò)清理 Redis 里的限流鍵來(lái)手動(dòng)解鎖。重新部署時(shí)想取消該限制可以在.env里調(diào)整相關(guān)安全配置具體變量名隨版本不同而變化最新版可在社區(qū)版源碼里搜incorrect password。清理 Redis 的方法docker compose exec redis redis-cli # 查看匹配的 key keys *login* keys *password* # 刪除對(duì)應(yīng) key del key注意這里用docker compose exec redis而不是docker exec因?yàn)?Dify 目錄下的 Compose 文件里定義了 redis 服務(wù)名直接用服務(wù)名更不容易拼寫(xiě)錯(cuò)誤。順便說(shuō)一句如果你忘了管理員密碼重置密碼的思路也是進(jìn)數(shù)據(jù)庫(kù)操作。Dify 的db容器里是 PostgreSQL可以用docker compose exec db psql -U postgres -d dify去操作 user 表來(lái)改密碼哈?;蛘吒?jiǎn)單的辦法是把管理員密碼通過(guò) API 重置具體看版本對(duì)應(yīng)的文檔。4.3 Docker Compose 和 docker run 混用導(dǎo)致的環(huán)境殘留這也是一個(gè)很容易讓人頭疼的點(diǎn)。你可能會(huì)搜到網(wǎng)上有人用docker run -d --name dify...直接單容器跑或者用了比較舊的docker-compose帶橫線命令而新版本用的是docker compose帶空格。兩個(gè)工具讀寫(xiě)同樣的容器和網(wǎng)絡(luò)但管理方式不同容易造成“誒我明明docker compose down了為什么端口還被占用”的困惑。我建議統(tǒng)一用新版的docker compose命令。查看 Compose 項(xiàng)目狀態(tài)時(shí)docker compose ls如果發(fā)現(xiàn)有殘留的舊容器用docker ps -a找出來(lái)刪掉再重新docker compose up -d。端口占用查起來(lái)很煩但大多數(shù)“端口被占用”其實(shí)都是上一輪沒(méi)刪干凈的容器在作祟。4.4 工作流、變量賦值和知識(shí)庫(kù)流水線的常見(jiàn)報(bào)錯(cuò)Dify 做智能體平臺(tái)的強(qiáng)大之處在于可視化的 workflow 編排和知識(shí)庫(kù)流水線。但運(yùn)行期最常見(jiàn)的問(wèn)題反而不是 workflow 邏輯本身而是底層組件的狀態(tài)。如果你在知識(shí)庫(kù)上傳文檔后一直顯示“處理中”或“索引失敗”先別去改 workflow 節(jié)點(diǎn)而是檢查這三個(gè)東西weaviate 向量數(shù)據(jù)庫(kù)是否 healthy。docker compose ps看 weaviate 狀態(tài)如果不是 healthy用docker compose logs weaviate看日志。啟動(dòng)失敗多半是/var/lib/weaviate目錄權(quán)限或者磁盤(pán)空間問(wèn)題。worker 容器是否在工作。文檔切塊、向量化是異步任務(wù)如果 worker 起不來(lái)知識(shí)庫(kù)就一直處理中。看docker compose logs worker有沒(méi)有報(bào)錯(cuò)。redis 里有沒(méi)有堆積任務(wù)。docker compose exec redis redis-cli -n 0 LLEN queue可以看隊(duì)列長(zhǎng)度。如果隊(duì)列一直增長(zhǎng)說(shuō)明 worker 消費(fèi)不了可能是模型提供商 API key 配置有誤導(dǎo)致一直重試。變量賦值不生效也是 Dify 工作流里被吐槽最多的問(wèn)題之一。其實(shí)大部分情況是變量作用域錯(cuò)了。Dify 里的變量有全局變量、對(duì)話變量、流程變量三種流程變量的賦值節(jié)點(diǎn)需要放在被引用節(jié)點(diǎn)之前否則在運(yùn)行時(shí)拿到的就是空值。調(diào)試方法是在 workflow 里加一個(gè)“日志輸出”節(jié)點(diǎn)把變量打出來(lái)看一眼比對(duì)著配置抓頭有效率得多。4.5 Dify 在線升級(jí)保留數(shù)據(jù)規(guī)避不可逆錯(cuò)誤如果你想從老版本升級(jí)到新版本比如為了體驗(yàn)社區(qū)版 1.10 的多租戶功能升級(jí)過(guò)程稍有不慎就可能把數(shù)據(jù)搞壞。官方升級(jí)路徑大體是這樣cd dify git pull origin main docker compose down docker compose pull docker compose up -d但有幾個(gè)坑你必須知道docker compose down不會(huì)刪除 volume所以數(shù)據(jù)理論上還在。但如果你手賤追加了-v參數(shù)docker compose down -vvolume 會(huì)被刪掉數(shù)據(jù)庫(kù)全沒(méi)。這是個(gè)不可逆操作一定別犯。升級(jí)前備份數(shù)據(jù)庫(kù)最穩(wěn)妥的方式是用 pg_dumpdocker compose exec db pg_dump -U postgres dify dify_backup_$(date %Y%m%d).sql新版 Dify 的.env文件會(huì)增加新配置項(xiàng)直接git pull后舊.env可能缺變量。建議先備份舊.env然后用新.env.example對(duì)比補(bǔ)齊新增項(xiàng)再啟動(dòng)。從舊版本跨大版本升級(jí)比如 1.0 直接換 1.10極有可能遇到數(shù)據(jù)庫(kù)遷移失敗因?yàn)橹虚g跳過(guò)太多版本。穩(wěn)妥做法是逐步升級(jí)或者用官方提供的遷移腳本。社區(qū)版 1.10 的多租戶功能確實(shí)香允許一個(gè) Dify 實(shí)例里開(kāi)多個(gè)獨(dú)立的租戶空間互相隔離數(shù)據(jù)。但升級(jí)后多租戶管理界面在“管理后臺(tái)”里要在控制臺(tái)找到“多租戶”入口創(chuàng)建租戶需要手動(dòng)分配配額。這個(gè)功能對(duì)于培訓(xùn)機(jī)構(gòu)和小型 SaaS 項(xiàng)目特別實(shí)用不用再為每個(gè)客戶單獨(dú)部署一套 Dify而是直接在控制臺(tái)開(kāi)租戶單獨(dú)配置模型供應(yīng)商和知識(shí)庫(kù)。5. 一套通用的排查方法論和一個(gè)防坑清單前面按階段講了很多具體報(bào)錯(cuò)最后我想分享一個(gè)我在多次“部署 Dify 翻車(chē)”中總結(jié)出來(lái)的通用排查思路以及部署前一定要過(guò)一遍的防坑清單。這些東西比單個(gè)報(bào)錯(cuò)的解法更重要因?yàn)檎莆樟朔椒ㄓ龅經(jīng)]見(jiàn)過(guò)的報(bào)錯(cuò)你也不會(huì)慌。5.1 四層排查法從鏡像到應(yīng)用逐層剝我習(xí)慣把 Dify 運(yùn)行問(wèn)題分成四層遇到任何報(bào)錯(cuò)先看屬于哪一層層級(jí)判斷方式常用命令鏡像層鏡像是否拉取成功、是否是最新版本docker images、docker pull容器層容器是否啟動(dòng)、是否崩潰、狀態(tài)是否 healthydocker compose ps、docker logs -f service網(wǎng)絡(luò)層容器之間是否能連通、能否解析 DNSdocker network ls、docker exec container ping other應(yīng)用層Dify 自身報(bào)錯(cuò)、模型調(diào)用、知識(shí)庫(kù)索引瀏覽器控制臺(tái)、docker compose logs api/worker舉個(gè)例子你打開(kāi) Dify 控制臺(tái)發(fā)現(xiàn)知識(shí)庫(kù)上傳文檔一直轉(zhuǎn)圈。不要直接去改代碼或重裝按層排查先看 api/worker 容器狀態(tài)docker compose ps。如果顯示 unhealthy說(shuō)明是容器層問(wèn)題。再看 worker 日志docker compose logs worker。如果日志里是網(wǎng)絡(luò)超時(shí)可能是網(wǎng)絡(luò)層問(wèn)題查容器 DNS 或外網(wǎng)連通性。如果日志出現(xiàn)connection refused查數(shù)據(jù)庫(kù)或 redis 是否可連接這屬于網(wǎng)絡(luò)層 容器層的交叉問(wèn)題。都正常的話才考慮應(yīng)用層比如模型 API key 失效、知識(shí)庫(kù)文件格式不支持等。這套排查法能幫你把“網(wǎng)絡(luò)問(wèn)題偽裝成應(yīng)用問(wèn)題”的情況識(shí)別出來(lái)。我在實(shí)際中看到太多人一上來(lái)就重裝 Dify結(jié)果重裝完發(fā)現(xiàn)還是同樣的問(wèn)題因?yàn)楦蚋静辉趹?yīng)用層而是宿主機(jī) DNS 配錯(cuò)了。5.2 部署前的 5 分鐘防坑清單每次部署 Dify 前花五分鐘過(guò)一遍下面這個(gè)清單能避開(kāi)八成的坑[ ] 宿主機(jī)的 80 端口沒(méi)被占用或者已經(jīng)改好.env里EXPOSE_NGINX_PORT[ ] 磁盤(pán)剩余空間 ≥ 20GB鏡像、volume、日志都很吃空間[ ] 能正常ping通外網(wǎng)DNS 解析正常[ ]docker version能正常連接 Enginedocker compose version是 v2 版本[ ] 拉鏡像的加速源已配置我每次在新機(jī)器部署都會(huì)先跑一次docker run --rm hello-world確認(rèn) Docker 從拉取到運(yùn)行整條鏈路是通的再碰 Dify。這個(gè)測(cè)試雖然簡(jiǎn)單但能隔離掉“Docker 本身有問(wèn)題”和“Dify 配置有問(wèn)題”兩種情況。我自己在跑 Dify 的過(guò)程中最大的體會(huì)是Dify 的報(bào)錯(cuò)信息大多數(shù)時(shí)候是“結(jié)果”而不是“原因”。比如 SSL 錯(cuò)誤背后可能是反代配置缺頭、登錄被鎖背后是安全策略、知識(shí)庫(kù)處理失敗背后是向量庫(kù)沒(méi)起來(lái)。如果只是按報(bào)錯(cuò)文本直接搜索往往搜出來(lái)的都是“控制臺(tái)清緩存”“重啟再試”這類(lèi)治標(biāo)不治本的方案。先把整個(gè) Docker 環(huán)境的健康度確認(rèn)到位再逐層往上查這套方法論部署任何別的容器化項(xiàng)目同樣適用。最后再分享一個(gè)小技巧部署 Dify 的機(jī)器上可以養(yǎng)成交替使用docker compose ps和docker compose logs --tail50 service的習(xí)慣。前者看的是“容器現(xiàn)在什么狀態(tài)”后者看的是“發(fā)生了什么導(dǎo)致這個(gè)狀態(tài)”。這兩個(gè)命令組合起來(lái)排查效率遠(yuǎn)超直接百度報(bào)錯(cuò)文本。后續(xù)如果想把 Dify 接入 Cursor、或者做二開(kāi)、接入外部知識(shí)庫(kù)也都是從這個(gè)穩(wěn)定的容器底座開(kāi)始基礎(chǔ)打好了上層怎么搭都順。