Helm Chart 完整部署指南 ─ 从 Kubernetes 环境准备到 Ingress 发布和运行
Kubernetes + Helm Chart 是在生产环境中运行 Dify Enterprise 时推荐的部署路径。在本文中,我们将全面讲解从检查集群先决条件到 helm install、Ingress 设置、操作验证和升级/回滚的所有内容。
必备知识:假设您了解 Kubernetes 的基本概念(Pod、Deployment、Service、PVC、Ingress)以及
kubectl的基本操作。如果您先尝试 Docker Compose 版本,会更容易理解服务配置。 → Docker Compose デプロイガイド
1.先决条件
1.1 Kubernetes 集群要求
| 项目 | 要求 |
|---|---|
| Kubernetes 版本 | 1.24 或更高 |
| Helm | 3.14 或更高 |
| 节点数量(推荐) | 3 个或更多节点(生产) |
| 每个节点的推荐规格 | 4 vCPU / 16 GB RAM 或更多 |
| 存储类 | 需要具有动态配置的 StorageClass |
| 入口控制器 | nginx-ingress 或同等控制器正在运行 |
1.2 外部资源
Dify Enterprise 的 Helm Chart 假设您已提前准备好以下外部资源。对于生产环境,我们建议使用托管服务。
| 资源 | 应用 | 推荐的托管服务示例 |
|---|---|---|
| PostgreSQL | 主数据库 | Amazon RDS、Cloud SQL、Azure Database for PostgreSQL |
| Redis | 缓存/任务队列 | Amazon ElastiCache、云内存存储、Azure Redis 缓存 |
| 对象存储 | 文件/文档存储 | Amazon S3、Google 云存储、Azure Blob 存储 |
| 矢量数据库 | 知识库索引 | Weaviate 云、Qdrant 云、Zilliz (Milvus) |
注意:可以配置 Helm Chart 以包含这些中间件,但在生产环境中,从数据持久性和可操作性的角度来看,我们建议使用托管服务。
1.3 检查工具版本
# Kubernetes バージョン確認(kubectl 1.28+ では --short は廃止のため -o yaml を使用)
kubectl version -o yaml
# Helm バージョン確認
helm version --short
# クラスタのノード状態確認
kubectl get nodes -o wide
# StorageClass の確認
kubectl get storageclass
# Ingress Controller の確認
kubectl get pods -n ingress-nginx
2.命名空间设计
2.1 为什么命名空间设计很重要
Dify Enterprise 有一个规范:许可证链接到命名空间。这意味着稍后更改您的命名空间可能需要您重新激活您的许可证。请一开始就仔细设计。
2.2 推荐的命名空间配置
# 開発環境
kubectl create namespace dify-dev
# ステージング環境
kubectl create namespace dify-staging
# 本番環境
kubectl create namespace dify-prod
2.3 命名空间设计指南
| 环境 | 命名空间 | 用途 | 许可证 |
|---|---|---|---|
| 发展 | dify-dev | 功能验证、开发人员测试 | 开发许可证 |
| 分期 | dify-staging | 发布前验证、负载测试 | 演出许可证 |
| 生产 | dify-prod | 最终用户的生产运营 | 生产许可证 |
# 以降の手順では本番環境を例に進めます
export NAMESPACE=dify-prod
kubectl config set-context --current --namespace=${NAMESPACE}
3.添加Helm存储库
⚠️ 重要:Dify 没有官方维护的 Helm Chart 仓库(
helm.dify.ai不存在)。OSS 部署需选用社区维护的 Chart 之一。Enterprise 版通过私有 OCI registry 分发,由 LangGenius / 合作伙伴提供。
3.1 存储库注册(社区 Chart 示例)
主要社区 Chart 选项(截至 2026-05):
| 提供者 | 仓库 |
|---|---|
| @BorisPolonsky(最常用) | https://github.com/BorisPolonsky/dify-helm |
| @LeoQuote (douban) | https://github.com/douban/charts/tree/master/charts/dify |
| @magicsong | https://github.com/magicsong/ai-charts |
| @Ruiruiz30(AKS Pipeline) | https://github.com/Ruiruiz30/Dify-helm-chart-AKS |
# 示例:使用 BorisPolonsky/dify-helm
git clone https://github.com/BorisPolonsky/dify-helm.git
cd dify-helm
# 或者将其作为 chart dependency 通过 raw GitHub 引用
# 注意:community charts 没有统一的 helm repo URL,
# 通常通过 git clone 后 `helm install` 本地路径
helm install dify-staging . -f values.staging.yaml
如使用 Dify Enterprise,请联系 LangGenius / 合作伙伴获取私有 OCI registry 凭证 + Chart 版本号。Enterprise Chart 与上面任何 OSS 社区 Chart values schema 都不通用,请勿混用。
3.2 检查默认值
# デフォルトの values.yaml を確認(全設定項目の一覧)
helm show values dify/dify > values-default.yaml
# ファイルを開いて構造を把握
less values-default.yaml
我们建议创建自定义值文件并覆盖它,而不是直接编辑默认值。
4. 自定义values.yaml
4.1 创建自定义值文件
以下是生产环境的自定义 values.yaml 配置示例。
# values-prod.yaml
# Dify Enterprise 本番環境設定
# ── グローバル設定 ──
global:
# 外部からアクセスする URL
host: "dify.example.com"
enableTLS: true
edition: "enterprise"
# シークレットキー(必ず変更)
secretKey: "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# ── API サービス ──
api:
replicaCount: 2
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
env:
LOG_LEVEL: "INFO"
# ── Worker サービス ──
worker:
replicaCount: 2
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
# ── Web フロントエンド ──
web:
replicaCount: 2
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
# ── Plugin Daemon ──
pluginDaemon:
replicaCount: 1
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
4.2 外部数据库配置
# values-prod.yaml(続き)
# ── PostgreSQL(外部マネージドサービス) ──
postgresql:
# Chart 内蔵の PostgreSQL を無効化
enabled: false
externalPostgresql:
host: "dify-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com"
port: 5432
username: "dify"
password: "your-secure-password" # Secret 経由を推奨
database: "dify"
sslMode: "require"
# ── Redis(外部マネージドサービス) ──
redis:
enabled: false
externalRedis:
host: "dify-redis.xxxxxxxxxxxx.apne1.cache.amazonaws.com"
port: 6379
password: "your-secure-password"
useTLS: true
4.3 存储设置
# values-prod.yaml(続き)
# ── オブジェクトストレージ ──
storage:
type: "s3"
s3:
endpoint: "https://s3.ap-northeast-1.amazonaws.com"
bucketName: "dify-prod-storage"
accessKey: "AKIAIOSFODNN7EXAMPLE"
secretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
region: "ap-northeast-1"
4.4 向量数据库设置
# values-prod.yaml(続き)
# ── ベクトルデータベース ──
vectorStore:
type: "weaviate" # weaviate | qdrant | milvus | pgvector
weaviate:
endpoint: "https://your-cluster.weaviate.network"
apiKey: "your-weaviate-api-key"
# Qdrant を使用する場合
# qdrant:
# endpoint: "https://your-cluster.qdrant.io"
# apiKey: "your-qdrant-api-key"
4.5 入口设置
# values-prod.yaml(続き)
# ── Ingress ──
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
hosts:
- host: "dify.example.com"
paths:
- path: /
pathType: Prefix
tls:
- secretName: dify-tls
hosts:
- "dify.example.com"
4.6 持久卷设置
使用Chart内置中间件(用于验证环境)时,需要进行PVC设置。
# 検証環境向け: Chart 内蔵ミドルウェア使用時
postgresql:
enabled: true
persistence:
enabled: true
storageClass: "gp3"
size: "50Gi"
redis:
enabled: true
persistence:
enabled: true
storageClass: "gp3"
size: "10Gi"
5. 管理秘密
5.1 创建 Kubernetes Secret
我们建议使用 Kubernetes Secret,而不是直接在 values.yaml 中写入密码。
# データベースパスワードの Secret
kubectl create secret generic dify-db-secret \
--namespace=${NAMESPACE} \
--from-literal=password='your-secure-db-password'
# Redis パスワードの Secret
kubectl create secret generic dify-redis-secret \
--namespace=${NAMESPACE} \
--from-literal=password='your-secure-redis-password'
# Dify シークレットキーの Secret
kubectl create secret generic dify-secret-key \
--namespace=${NAMESPACE} \
--from-literal=secretKey="$(openssl rand -base64 42)"
# S3 認証情報の Secret
kubectl create secret generic dify-s3-secret \
--namespace=${NAMESPACE} \
--from-literal=accessKey='AKIAIOSFODNN7EXAMPLE' \
--from-literal=secretKey='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
5.2 value.yaml 中的秘密引用
# Secret を参照する values.yaml の記述例
externalPostgresql:
host: "dify-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com"
port: 5432
username: "dify"
database: "dify"
existingSecret: "dify-db-secret"
existingSecretPasswordKey: "password"
6. 运行 Helm 安装
6.1 通过试运行初步确认
# テンプレートのレンダリング結果を確認(実際にはデプロイしない)
helm template dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml > rendered.yaml
# レンダリング結果を確認
less rendered.yaml
# dry-run で Kubernetes API への送信をシミュレート
helm install dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml \
--dry-run
6.2 执行安装
# Helm Chart のインストール
helm upgrade --install dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml \
--wait \
--timeout 10m
helm upgrade --install 是幂等的,第一次作为安装,第二次以后作为升级。
6.3 检查安装状态
# Helm リリースの確認
helm list --namespace=${NAMESPACE}
# リリースの詳細確認
helm status dify --namespace=${NAMESPACE}
# 適用された values の確認
helm get values dify --namespace=${NAMESPACE}
7. 部署后验证
7.1 检查 Pod 状态
# 全 Pod の状態を確認
kubectl get pods --namespace=${NAMESPACE} -o wide
# 期待される出力例
# NAME READY STATUS RESTARTS AGE NODE
# dify-api-xxxxxxxxxx-xxxxx 1/1 Running 0 5m node-1
# dify-api-xxxxxxxxxx-yyyyy 1/1 Running 0 5m node-2
# dify-worker-xxxxxxxxxx-xxxxx 1/1 Running 0 5m node-1
# dify-worker-xxxxxxxxxx-yyyyy 1/1 Running 0 5m node-3
# dify-web-xxxxxxxxxx-xxxxx 1/1 Running 0 5m node-2
# dify-web-xxxxxxxxxx-yyyyy 1/1 Running 0 5m node-3
# Pod が Running にならない場合
kubectl describe pod <pod-name> --namespace=${NAMESPACE}
kubectl logs <pod-name> --namespace=${NAMESPACE}
7.2 检查服务和入口
# Service の確認
kubectl get svc --namespace=${NAMESPACE}
# Ingress の確認
kubectl get ingress --namespace=${NAMESPACE}
# Ingress の詳細(割り当てられた IP / ホスト名を確認)
kubectl describe ingress dify --namespace=${NAMESPACE}
7.3 检查 PVC
# 永続化ボリュームの状態確認
kubectl get pvc --namespace=${NAMESPACE}
# 全 PVC が Bound であることを確認
# NAME STATUS VOLUME CAPACITY STORAGECLASS
# dify-postgresql-0 Bound pvc-xxxxxxxx 50Gi gp3
# dify-redis-0 Bound pvc-yyyyyyyy 10Gi gp3
7.4 DNS和访问确认
# Ingress の EXTERNAL-IP を取得
INGRESS_IP=$(kubectl get ingress dify --namespace=${NAMESPACE} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Ingress IP: ${INGRESS_IP}"
# DNS が設定されるまでの間、/etc/hosts で一時的に名前解決
# sudo sh -c "echo '${INGRESS_IP} dify.example.com' >> /etc/hosts"
# ヘルスチェック
curl -sk https://dify.example.com/v1/health
# ブラウザでアクセス
# https://dify.example.com
7.5 综合操作检查表
# 以下のコマンドで全リソースの状態を一括確認
kubectl get all,ingress,pvc,secret --namespace=${NAMESPACE}
| 检查项目 | 命令/方法 | 预期结果 |
|---|---|---|
| 整个吊舱 | kubectl get pods | 全部运行 (1/1) |
| 服务 | kubectl get svc | ClusterIP 已分配 |
| 入口 | kubectl get ingress | 已分配地址 |
| 聚氯乙烯 | kubectl get pvc | 全部绑定 |
| API 健康 | curl /v1/health | {"status": "ok"} |
| 用户界面访问 | 浏览器中的网址 | 显示初始设置屏幕 |
| 数据库连接 | API Pod 日志 | 没有连接错误 |
| Redis连接 | Worker Pod 日志 | 没有连接错误 |
8.升级与回滚
8.1 升级
# リポジトリを最新化
helm repo update
# 新バージョンの確認
helm search repo dify/dify --versions
# values.yaml を更新した後にアップグレード
helm upgrade dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml \
--wait \
--timeout 10m
# 特定バージョンを指定してアップグレード
helm upgrade dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml \
--version 1.2.3 \
--wait
8.2 升级前检查清单
| 步骤 | 命令 | 目的 |
|---|---|---|
| 1.查看当前版本 | helm list -n ${NAMESPACE} | 当前发布信息 |
| 2. 检查变更 | helm diff upgrade dify dify/dify -f values-prod.yaml | 预先检查差异(helm-diff 插件) |
| 3.数据库备份 | 托管服务快照 | 数据保护 |
| 4. 试运行 | helm upgrade --dry-run ... | 模板确认 |
| 5.执行 | helm upgrade ... | 升级执行力 |
| 6. 验证 | kubectl get pods、curl /health | 确认正常运行 |
8.3 回滚
# リリース履歴の確認
helm history dify --namespace=${NAMESPACE}
# 1 つ前のリビジョンにロールバック
helm rollback dify --namespace=${NAMESPACE}
# 特定のリビジョンにロールバック
helm rollback dify 3 --namespace=${NAMESPACE}
# ロールバック後の確認
kubectl get pods --namespace=${NAMESPACE}
helm status dify --namespace=${NAMESPACE}
9. 缩放
9.1 手动缩放
# values.yaml を変更して適用
# api:
# replicaCount: 4
helm upgrade dify dify/dify \
--namespace=${NAMESPACE} \
-f values-prod.yaml
# または kubectl で直接スケール(一時的な対応)
kubectl scale deployment dify-api --replicas=4 --namespace=${NAMESPACE}
9.2 配置 HPA(水平 Pod 自动缩放器)
# values-prod.yaml に追加
api:
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
worker:
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 8
targetCPUUtilizationPercentage: 70
# HPA の状態確認
kubectl get hpa --namespace=${NAMESPACE}
# HPA の詳細確認
kubectl describe hpa dify-api --namespace=${NAMESPACE}
10. 监控和日志记录
10.1 检查Pod日志
# API サーバーのログ
kubectl logs -f deployment/dify-api --namespace=${NAMESPACE}
# Worker のログ
kubectl logs -f deployment/dify-worker --namespace=${NAMESPACE}
# 複数 Pod のログを同時に確認(stern を使用)
# brew install stern (macOS)
stern dify-api --namespace=${NAMESPACE}
stern dify-worker --namespace=${NAMESPACE}
10.2 资源使用
# Pod のリソース使用量(metrics-server が必要)
kubectl top pods --namespace=${NAMESPACE}
# ノードのリソース使用量
kubectl top nodes
10.3 Prometheus / Grafana 集成
对于生产环境,我们建议使用 Prometheus + Grafana 监控指标。
# values-prod.yaml に追加
api:
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "5001"
prometheus.io/path: "/metrics"
11. 故障排除
11.1 Pod 无法启动(待处理)
# Pod の詳細を確認
kubectl describe pod <pod-name> --namespace=${NAMESPACE}
# よくある原因:
# - リソース不足 → ノードの追加またはリソースリクエストの削減
# - PVC がバインドされない → StorageClass の確認
# - イメージ Pull 失敗 → imagePullSecrets の確認
11.2 Pod 发生 CrashLoopBackOff
# コンテナのログを確認
kubectl logs <pod-name> --namespace=${NAMESPACE} --previous
# よくある原因:
# - データベース接続失敗 → externalPostgresql の設定確認
# - Redis 接続失敗 → externalRedis の設定確認
# - SECRET_KEY が未設定 → values.yaml の global.secretKey 確認
11.3 Ingress无法访问
# Ingress Controller のログ
kubectl logs -f deployment/ingress-nginx-controller -n ingress-nginx
# Ingress リソースの確認
kubectl describe ingress dify --namespace=${NAMESPACE}
# バックエンド Service のエンドポイント確認
kubectl get endpoints --namespace=${NAMESPACE}
# よくある原因:
# - Ingress Controller が未インストール
# - className の不一致
# - TLS Secret が存在しない
11.4 知识库不起作用
# Worker のログを確認
kubectl logs -f deployment/dify-worker --namespace=${NAMESPACE}
# ベクトルデータベースへの接続確認
kubectl exec -it deployment/dify-api --namespace=${NAMESPACE} -- \
curl -s http://weaviate-endpoint:8080/v1/.well-known/ready
# よくある原因:
# - ベクトルデータベースの接続情報が不正
# - Worker がダウンしている
11.5 常见错误及解决方法
| 错误 | 原因 | 解决方案 |
|---|---|---|
ImagePullBackOff | 注册表认证失败 | 设置 imagePullSecrets |
Pending (PVC) | 没有存储类 | 使用kubectl get sc检查并创建 |
CrashLoopBackOff | 设置错误 | 使用 kubectl logs --previous 检查日志 |
502 Bad Gateway | 后端未启动 | 检查 Pod 状态和服务端点 |
certificate verify failed | TLS 设置不足 | 检查证书管理器日志和秘密 |
12. 生产运营的最佳实践
12.1 value.yaml 的 Git 管理
# values ファイルを Git で管理
mkdir -p dify-helm-config
cd dify-helm-config
git init
# 環境ごとの values ファイル
# values-dev.yaml
# values-staging.yaml
# values-prod.yaml
# Secret 値は values に含めず、Kubernetes Secret で管理
# .gitignore に機密情報を含むファイルを追加
echo "values-*-secrets.yaml" >> .gitignore
12.2 备份策略
| 目标 | 方法 | 频率 |
|---|---|---|
| PostgreSQL | 托管服务自动备份+手动快照 | 每日自动+预发布手动 |
| Redis | 托管服务自动备份 | 每日自动 |
| 对象存储 | 版本控制+跨区域复制 | 实时 |
| 矢量数据库 | 快照 | 每周 |
| 掌舵价值观 | Git 存储库 | 关于改变 |
12.3 命名空间和许可证之间的关系
graph LR
subgraph "Kubernetes クラスタ"
NS1[dify-dev<br/>namespace]
NS2[dify-staging<br/>namespace]
NS3[dify-prod<br/>namespace]
end
L1[開発 License] --> NS1
L2[ステージング License] --> NS2
L3[本番 License] --> NS3
style L1 fill:#e1f5fe
style L2 fill:#fff3e0
style L3 fill:#e8f5e9
重要说明:
- 许可证链接到命名空间,因此更改命名空间名称需要重新激活。
- 无法使用一个许可证部署到多个命名空间
- 许可证到期日期和席位数量取决于 Dify Enterprise 合同
总结
在本文中,我们使用以下流程解释了 Dify Enterprise 的 Helm Chart 部署。
- 前提条件 – Kubernetes/Helm版本要求及外部资源准备
- 命名空间设计 – 考虑与License联动的环境分离
- 添加 Helm 存储库 – 获取图表并检查值
- 自定义values.yaml – 外部DB、存储和Ingress设置
- 秘密管理 – 安全处理密码和认证信息
- Helm Install – 从试运行到安装执行
- 部署后验证 – 检查 Pod、服务、Ingress 和 PVC
- 升级和回滚 – 安全更新程序
- 缩放 – 手动缩放和HPA设置
- 监控和日志记录 – 在运行过程中检查日志并收集指标
- 故障排除 – 常见问题及解决步骤
使用 Helm Chart 进行 Kubernetes 部署的初始设置比 Docker Compose 更复杂,但您可以利用生产操作所需的所有功能,例如高可用性、自动扩展和滚动更新。首先,在开发环境中对其进行彻底测试,然后在将其部署到生产环境之前对其进行暂存。
参考资料
-Dify Helm Chart - Dify Enterprise Docs -Kubernetes Prerequisites - Dify Enterprise Docs -Resources Checklist - Dify Enterprise Docs -Helm を使って minikube で Dify をデプロイしてみた - Zenn -Dify を Azure Kubernetes Service (AKS) で動かせるようにしました - note