基礎架構/自架 AI 平台
從 Dify v1.9.2 升級至 v1.13.3 的方法與容易遇到的問題 #
對舊版 docker-compose.yaml 做過越多客製調整,自架 Dify 的升級就會變得越困難。
這次我們記錄了將以 Docker Compose 運作的 Dify 從 v1.9.2 升級至 v1.13.3 的完整過程,
並將機敏資訊遮蔽後對外公開。
比起單純更新映像檔標籤(image tag),最安全的做法是以官方 compose 為基底重新替換,再還原環境特有的設定。
本文中的網域名稱、電子郵件地址、API 金鑰、驗證憑證、憑證路徑、主機名稱,以及部分磁碟區(volume)設定, 皆已進行遮蔽或抽象化處理,以避免識別出實際環境。
為什麼「只更新映像檔標籤」風險很高 #
當版本差距較大時,Dify 可能無法僅靠單純更新容器映像檔來吸收所有變更。 比對實際差異後,本次更新有以下幾個重點。
服務設定的變更 #
在新版官方 compose 中,資料庫服務名稱預期會是 db_postgres 而非 db,
並且新增了 worker_beat 與權限初始化流程,可見架構上有明顯差異。
周邊元件的更新 #
Plugin Daemon、Sandbox、Weaviate 等 Dify 核心以外的元件,同樣都是本次更新的對象。 若沿用舊有的設定檔,很容易造成啟動後部分功能故障的狀態。
既有客製化設定的存在 #
在長期運作的環境中,憑證掛載、自訂環境變數、外掛設定等客製化設定往往會逐漸累積。 這些內容並不會自動被納入官方 compose,因此需要手動還原。
設定檔的逐漸失控(Drift) #
長期直接編輯舊版 compose,會讓人難以分辨哪些是官方設定、哪些是公司自訂的設定。 在這種狀態下進行整批更新,可能造成難以復原的故障。
與其繼續沿用既有的 compose,這次我們改以官方 v1.13.3 的 compose 為基底進行替換,僅還原必要的差異部分, 結果在更新後的可讀性與可維護性上都大幅提升。
本次的升級策略 #
- 首先,進行包含
docker/volumes在內的完整備份 - 在另一個目錄取得官方 v1.13.3 版本,以建立差異比對基準
- 將
docker-compose.yaml替換為官方版本 - 僅還原
.env及 TLS 掛載等環境特有的設定 - 依新版假設更新 Sandbox 設定檔
- 啟動前先以
docker compose config驗證語法 - 啟動後不只檢查 UI,也要驗證 Knowledge/Plugin/程式碼執行功能
1. 首先進行備份 #
最重要的是確保能還原到更新前的 compose 與磁碟區狀態。 尤其是 Weaviate 或 PostgreSQL,絕對有可能出現更新後需要回滾(rollback)的情境。
cd /srv/dify/docker
TS=$(date +%Y%m%d%H%M%S)
cp -a docker-compose.yaml "docker-compose.yaml.${TS}.bak"
cp -a .env ".env.${TS}.bak"
[ -f volumes/sandbox/conf/config.yaml ] && \
cp -a volumes/sandbox/conf/config.yaml "volumes/sandbox/conf/config.yaml.${TS}.bak"
tar -czf "/root/dify-volumes-${TS}.tgz" volumes
這裡展示的路徑是公開發表用的範例。在實際生產環境中,請依貴公司自身環境的目錄結構進行調整。
2. 取得官方 v1.13.3 版本 #
不直接修改既有目錄,而是取得至另一個獨立目錄以便進行比對。 這個階段的重點在於不要覆寫既有的環境檔案。
cd /tmp
rm -rf dify-1.13.3
git clone --branch 1.13.3 https://github.com/langgenius/dify.git dify-1.13.3
取得後,至少比對以下三個檔案,能更容易理解本次更新需要吸收哪些變更:
docker-compose.yaml、.env.example,以及
volumes/sandbox/conf/config.yaml.example。
3. 以官方版本替換 Compose #
這次我們不再繼續修改既有的 compose,而是直接採用官方 v1.13.3 版本作為基底。 這麼一來,未來的升級也更容易追蹤「與官方版本的差異」。
cp /tmp/dify-1.13.3/docker/docker-compose.yaml /srv/dify/docker/docker-compose.yaml
cp /tmp/dify-1.13.3/docker/.env.example /srv/dify/docker/.env.example.1.13.3
cp /tmp/dify-1.13.3/docker/volumes/sandbox/conf/config.yaml.example \
/srv/dify/docker/volumes/sandbox/conf/config.yaml.example.1.13.3
關鍵在於替換 compose 後,不要立刻啟動服務。 請先還原
.env、憑證掛載、Sandbox 設定等環境特有的數值,之後再啟動。
4. 還原環境特有的設定 #
採用官方 compose 之後,僅以覆蓋(overlay)的方式還原正式運作所需的設定。 在我們的環境中,以下項目特別重要。
務必確認的項目 #
DB_HOST是否已設定為db_postgres- Weaviate 的 API 金鑰與 gRPC 端點
- NGINX 伺服器名稱與憑證路徑
- 公開 URL 與內部檔案 URL
- Plugin Daemon 相關的逾時設定
公開發表時需遮蔽的項目 #
- 網域名稱
- 電子郵件地址
- API 金鑰/機密資訊
- 實際的憑證檔名
- 內部磁碟區設定與主機名稱
DB_TYPE=postgresql
DB_HOST=db_postgres
DB_PORT=5432
VECTOR_STORE=weaviate
WEAVIATE_ENDPOINT=http://weaviate:8080
WEAVIATE_GRPC_ENDPOINT=grpc://weaviate:50051
WEAVIATE_API_KEY=<YOUR_WEAVIATE_API_KEY>
NGINX_SERVER_NAME=<YOUR_DOMAIN>
NGINX_HTTPS_ENABLED=true
NGINX_SSL_CERT_FILENAME=live/<YOUR_DOMAIN>/fullchain.pem
NGINX_SSL_CERT_KEY_FILENAME=live/<YOUR_DOMAIN>/privkey.pem
FILES_URL=https://<YOUR_DOMAIN>
INTERNAL_FILES_URL=http://api:5001
PLUGIN_MAX_EXECUTION_TIMEOUT=1800
重點在於不要照搬所有舊的環境變數,而是以新版官方 .env.example 為基礎,僅重新設定必要的項目。
特別是 DB_HOST 及 Weaviate 相關設定,若直接沿用舊 compose 的內容,很容易在啟動後產生錯誤。
5. 還原 NGINX 憑證掛載 #
替換為官方 compose 後,TLS 掛載設定可能會偏離貴公司環境的原始假設。 這次由於我們是在既有的主機目錄中管理憑證,因此僅針對 NGINX 服務重新調整了掛載設定。
services:
nginx:
volumes:
- ./nginx/ssl:/etc/ssl
- /path/to/external/letsencrypt:/etc/letsencrypt
若貴公司的架構是完全在 Certbot 容器內處理憑證,官方預設的掛載設定或許就已足夠。 但若是透過外部路徑管理憑證,替換後建議務必再次確認。
6. 更新 Sandbox 設定 #
經常被忽略的一環是 Sandbox 設定。
版本變更時,Python/Node.js 的路徑假設可能會有所調整,
而既有的 config.yaml 並不會自動隨之更新。
app:
port: 8194
debug: true
key: dify-sandbox
python_path: /opt/python/bin/python3
nodejs_path: /usr/local/bin/node
若沿用舊版的
config.yaml,容易出現 UI 能正常啟動,但僅有程式碼執行功能失效的情況。
更新後建議獨立驗證 Sandbox 功能。
7. 啟動前檢查語法、啟動後檢閱日誌 #
替換 compose 後,請先執行語法檢查。 接著再取得映像檔並啟動服務。
docker compose --profile weaviate --profile postgresql config > /tmp/dify.check.yaml
docker compose --profile weaviate --profile postgresql pull
docker compose --profile weaviate --profile postgresql up -d --remove-orphans
docker compose ps
docker compose logs --tail=120 api worker worker_beat plugin_daemon sandbox weaviate nginx
在更新作業中,切記不能因為啟動成功就認定更新已經成功。
api、worker、worker_beat、plugin_daemon、sandbox 各項服務的日誌,
在及早發現功能故障方面特別有幫助。
8. 更新後驗證清單 #
- 管理主控台能正常登入
- 既有應用程式的對話回應能正常回傳
- 知識庫(Knowledge)搜尋與重新索引成功
- 程式碼節點與 Sandbox 執行成功
- 外掛啟用與執行成功
- HTTPS 傳輸與憑證參照皆無問題
在像這次一樣周邊元件差異較大的更新中, 「UI 能否開啟」與「所有必要功能在正式環境中皆能運作」是兩個不同的問題。 事先依貴公司的使用情境決定關鍵驗證項目,能讓後續是否需要回滾的判斷更容易。
常見陷阱彙整 #
DB_HOST 不一致 #
若未依新版官方 compose 調整,API 與 Plugin Daemon 將無法連線至資料庫而發生錯誤崩潰。
db 與 db_postgres 之間的落差,是特別容易被忽略的一點。
遺漏 worker_beat #
若只關注主要的 API 與 worker,很容易忽略定期任務(periodic task)方面的問題。 更新後,建議一併驗證輔助服務。
忘記還原 TLS 掛載設定 #
將 compose 替換為官方版本時,憑證路徑可能會超出貴公司環境的原始假設範圍。 這會導致 HTTP 運作正常,但 HTTPS 卻失敗的狀況。
沿用舊版 Sandbox 設定 #
由於管理主控台仍能正常開啟,這一點很容易被忽略,但會直接影響程式碼執行功能是否正常。 分別驗證 UI 與 Sandbox 是關鍵所在。
本次更新的心得 #
Dify 環境運作的時間越長,「累積的客製差異」對升級時的影響,往往比「版本編號」本身更為顯著。 這次我們重新確認到的是:將對官方 compose 的修改降到最低,並以覆蓋(overlay)方式管理環境特有的設定, 能讓後續的升級與事故處理都大幅變得輕鬆許多。
若貴公司目前的環境正穩定運作於較舊的版本上,只要在更新前先整理好以下三點,整個流程就會順暢許多。
- 盤點並區分出源自官方的設定與公司自訂的設定
- 務必事先進行可回滾的備份
- 在啟動驗證之前,先決定好關鍵功能的驗證項目
對於 Dify 的重大版本更新而言,比起「延續舊版 compose 進行擴充」,「以新版官方 compose 重新奠基(rebase)」 是更安全的做法,也能讓日後回頭檢視時,設定內容依然清晰易懂。