安装 Dify

本指南使用 Dify Operator(基于 helm 的 OLM operator)在 Alauda Container Platform 上安装 Dify。请按顺序执行各步骤——每一步都依赖于上一步。

关于 Dify 的功能以及它会部署哪些组件,请参见 简介

概览

你需要原因
Dify operator 软件包先下载并按照通用软件包操作步骤上架,以便该 operator 显示在 OperatorHub 中(参见 上架软件包
外部 PostgreSQL 12+Dify 的主数据库(仅支持 PostgreSQL)
外部 Redis 6+(单机或 Sentinel)缓存 + Celery broker;不支持 Cluster 模式
外部 pgvector (可选)用于 RAG 的向量存储;如果不使用 RAG,请禁用
RWX PVC S3-compatible 存储为 API + Plugin Daemon 提供共享、可写存储
浏览器访问所需的 访问方式以下之一:NodePort/Service、单域名或双域名。域名和 TLS 证书通过 ACP 网络管理 注册。参见 步骤 4
集群内代理 (仅限受限网络)Marketplace 反向代理 + PyPI 镜像,用于离线安装插件

步骤 1 — 发布 Operator 软件包

从 Customer Support / Portal 下载 Dify operator 软件包,然后按照 上架软件包 中的说明上传该软件包,使其显示在 Marketplace / OperatorHub 中。

步骤 2 — 安装 Dify Operator

在 Alauda Container Platform 的 管理员 视图中:

  1. 打开 Marketplace / OperatorHub 并选择目标集群。
  2. 搜索 Dify,单击 安装,除非需要非默认命名空间,否则保持默认值不变。
  3. 等待卡片显示 已安装

步骤 3 — 准备外部依赖

PostgreSQL(必需)

使用 PostgreSQL 12+。最简单的方式是在 Data Services 中使用 PostgreSQL operator:先创建一个集群,然后为 Dify 创建一个空数据库(例如 dify)。记录主机、端口、用户名和密码。

Redis(必需 — 单机或 Sentinel)

使用 Redis 6.0+。通过 Data Services 创建。

  • 单机: 使用 Redis Sentinel 架构创建,切换到 YAML,设置 spec.arch: standalone,然后创建。将 rfr-<instance>-read-write Service 作为 Redis 主机。
  • Sentinel(HA): 保持 Sentinel 架构;在 步骤 6 中使用 Sentinel Service 端点 + 主节点名称。

pgvector — 向量存储 (可选,用于 RAG)

仅支持 pgvector。请使用安装了 pgvector 扩展的 PostgreSQL 实例。它可以与主数据库共享同一个主机(使用不同的数据库名),也可以使用独立主机。如果不使用 RAG,请跳过。

存储 — RWX PVC 或 S3

API、Worker、Worker-Beat 和 Plugin Daemon 需要共享的可写存储:

  • 一个在各工作负载之间共享的 ReadWriteMany (RWX) StorageClass,或者
  • 一个 S3-compatible 对象存储(MinIO、AWS S3、OBS 等)——在没有 RWX class 时推荐使用。

记录 StorageClass 名称,或者记录 S3 端点 + 区域 + bucket + access key。

步骤 4 — 确定并设置访问方式

Dify 面向浏览器,并且有两个访问面,因此 Dify 实例有两个 URL 字段:

  • Console URL — 管理员 / 应用创建者使用的构建界面(创建应用、配置模型、管理知识库)。
  • App URL — 终端用户打开的已发布应用(类似 /chat/<code> 的聊天 / agent 页面)。

这两个 URL 都必须与用户实际访问 Dify 的方式一致,否则前端无法加载。请从以下三个选项中选择一个——每个选项都说明了需要准备什么,以及两个 URL 如何填写。

选项使用场景需要准备的内容Console URL / App URL
A. NodePort / Service IP开发 / 内部使用;没有域名两者都设置为 http://<node-ip>:<nodeport>(同一个地址同时用于两者)
B. 单域名两个访问面使用同一个主机名1 个 ACP Certificate + 1 个 ACP Domain;Envoy Gateway + 一个 Gateway 资源两者都设置为 https://<host>
C. 双域名生产环境——管理员与终端用户分离访问(DNS / 证书 / 网络暴露不同)1 个 ACP Certificate(可同时覆盖两个域名,例如 wildcard)+ 2 个 ACP Domains;Envoy Gateway + 一个 Gateway 资源Console URL = https://<console-host>,App URL = https://<app-host>

对于 选项 A,这里无需额外配置——请直接进入步骤 5。对于 选项 B 和 C,请按如下方式设置 Gateway。

设置 Gateway(仅限选项 B 或 C)

三个子步骤:在 ACP 中注册域名(以及证书)→ 安装 Envoy Gateway → 创建引用证书 Secret 的 Gateway 资源。

1. 在 ACP 中注册域名

管理员 视图中,进入 网络管理域名创建域名,然后填写表单:

字段
类型域名(特定主机名)或泛域名(*.example.com
域名主机名,例如 dify-console.example.com
分配集群目标集群 + 项目(或所有项目)
证书Public Keytls.crt)和 Private Keytls.key)直接粘贴到表单中——ACP 会自动创建绑定的 TLS Secret

ACP 会创建:

  • 全局集群上的一个 Domain 自定义资源(apiVersion: crd.alauda.io/v2,集群级别,并带有 cluster.cpaas.io/name / project.cpaas.io/name 标签);
  • cpaas-system 命名空间中一个名为 <domain>-<random>kubernetes.io/tls Secret(例如 dify-console.example.com-xfd8x);Domain 的 cpaas.io/secret-ref 注解会记录该名称。

你可以从 Domain 详情页找到 Secret 名称。完整的 UI 参考:配置域名

然后将该主机名的 DNS 解析 到集群的负载均衡器地址。

对于选项 C 下的第二个主机名,重复上述步骤(双域名)。覆盖两个主机的同一张证书(例如 wildcard)可以复用——在两个 Domain 表单中填写相同的证书,或者通过 网络管理证书 先导入一次证书,再在创建域名时选择它(参见 创建证书)。

2. 安装 Envoy Gateway

ACP 包含 Alauda Build of Envoy Gateway operator。如果尚未安装,请从 Marketplace / OperatorHub 安装——参见 安装 Envoy Gateway operator

3. 创建 Gateway 资源

引用子步骤 1 中的证书 Secret。由于这些 Secret 位于 cpaas-system 中,而 Gateway listener 的 certificateRefs 默认只能解析 Gateway 自身命名空间中的 Secret,因此你有两种等价的方式:

  • 更简单 — 将 Gateway 放在 cpaas-system,这样就可以直接引用这些 Secret。
  • 跨命名空间 — 将 Gateway 保留在自己的命名空间中,并在 cpaas-system 中添加一个 ReferenceGrant,允许你的 Gateway 命名空间引用其中的 Secret。

选项 a — 将 Gateway 放在 cpaas-system 中:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: dify
  namespace: cpaas-system                 # co-located with the cert Secrets
spec:
  gatewayClassName: <envoy-gateway-class> # the GatewayClass exposed by Envoy Gateway
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.example.com"           # cover all hostnames registered in sub-step 1
      tls:
        mode: Terminate
        certificateRefs:
          - {name: <secret-name-from-ACP-domain>}   # from the Domain detail page
      allowedRoutes:
        namespaces:
          from: All

选项 b — 将 Gateway 放在其他命名空间中,并使用 ReferenceGrant

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: dify
  namespace: <gateway-namespace>
spec:
  gatewayClassName: <envoy-gateway-class>
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.example.com"
      tls:
        mode: Terminate
        certificateRefs:
          - {namespace: cpaas-system, name: <secret-name-from-ACP-domain>}
      allowedRoutes:
        namespaces:
          from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: dify-tls
  namespace: cpaas-system                 # grant lives in the Secret's namespace
spec:
  from:
    - {group: gateway.networking.k8s.io, kind: Gateway, namespace: <gateway-namespace>}
  to:
    - {group: "", kind: Secret}            # could also restrict by name

对于在同一个 Gateway 上使用两个不同主机名的选项 C,请添加第二个 listener(每个 listener 都可以指向自己的 hostnamecertificateRefs)。

步骤 5 — 提供插件安装代理 (仅限受限网络)

如果集群可以访问公网,请跳过此步骤。否则,请准备两个可通过 HTTP 访问的代理(可按任意方式部署——Nginx、现有 API gateway、devpi 等):

  • Marketplace 反向代理 — 代理到 https://marketplace.dify.ai并保留 Host: marketplace.dify.ai 请求头。记录其 Service URL。
  • PyPI 镜像 — 提供 PyPI simple index(例如代理 https://mirrors.aliyun.com/pypi/simple/,或任意 PyPI cache)。记录其 Service URL。
WARNING

Marketplace 代理 URL 必须是 FQDN(例如 http://dify-marketplace-proxy.<ns>.svc.cluster.local)——Dify 的内部 SSRF 代理(squid)无法解析集群内的短名称。

步骤 6 — 创建 Dify 实例

创建连接 Secret

# DB / Redis / pgvector passwords are read from key `password`
kubectl create secret generic dify-db       --from-literal=password='<db-password>'
kubectl create secret generic dify-redis    --from-literal=password='<redis-password>'    # omit if Redis has no auth
kubectl create secret generic dify-pgvector --from-literal=password='<pgvector-password>'
# S3 only — keys must be `accessKey` / `secretKey`
kubectl create secret generic dify-s3 --from-literal=accessKey='<ak>' --from-literal=secretKey='<sk>'

填写表单

OperatorHub已安装的 operator 中,选择 Dify,单击 创建 Dify,并填写表单。字段分组如下:

  • 访问 — 根据步骤 4 中选择的方案设置 Console URLApp URL(在选项 A 和 B 中,两者相同;在选项 C 中,两个主机名不同)。包含协议(NodePort 使用 http://,Gateway 使用 https://)。
  • 数据库 — 主机、端口、用户名(默认 postgres)、数据库名,以及 DB Secretdify-db)。如果 PostgreSQL 需要 SSL,请打开 SSL
  • Redis — 选择 StandaloneSentinel
    • Standalone: 主机、端口、Redis Secret(如果没有认证可留空)。
    • Sentinel: 逗号分隔的 host:port 列表、Master 名称Redis Secret,以及如果 Sentinel 本身需要认证,则还需要 Sentinel Secret
  • 向量存储(pgvector) — 开启 Enable。启用后需要填写:主机、端口、用户名、数据库名、Vector Secret
  • 存储 — 选择 PVCS3
    • PVC: RWX StorageClass 和大小。
    • S3: 端点、区域、API bucketPlugin bucketS3 Secretdify-s3),以及 Path-style addressing(MinIO 和大多数 S3-compatible 端点请打开;AWS 请关闭)。
  • HTTP Route仅在使用 Gateway 时(选项 B 或 C)显示。 设置 Gateway nameGateway namespace、可选的 Section name(listener)以及 Hostnames(必须被 Gateway listener 覆盖)。
  • 高级 → Plugin proxy仅限受限网络集群。 打开 Marketplace,并将 Marketplace URL 填写为步骤 5 中的代理地址(必须是 FQDN)。填写 PIP Mirror URL。打开 Ignore uv lock(否则 uv sync --frozen 会绕过镜像)。对于较慢的镜像,请增大 Plugin init timeout(例如 1200s)。如果你提供的是重新打包后的插件,请关闭 Verify plugin signature

以下是相同配置的 YAML 参考(对应表单的 YAML 视图):

consoleUrl: https://dify-console.example.com
appUrl:     https://dify-app.example.com

database:
  host: <postgres-host>
  port: 5432
  username: postgres
  name: dify
  secret: dify-db
  sslEnabled: false

redis:
  mode: standalone               # standalone | sentinel
  host: <redis-host>
  port: 6379
  secret: dify-redis             # omit if no auth
  cacheDB: 0
  brokerDB: 1

vectorStore:
  enabled: true                  # set false to disable RAG
  host: <pgvector-host>
  port: 5432
  username: postgres
  name: dify_vector
  secret: dify-pgvector

storage:
  type: PVC                      # PVC | S3
  storageClass: <rwx-storage-class>
  size: 20Gi

httpRoute:                       # Option B / C only
  gatewayName: dify
  gatewayNamespace: <gateway-namespace>
  hostnames:
    - dify-console.example.com
    - dify-app.example.com

proxy:                           # restricted network only
  marketplace: true
  marketplaceURL: http://dify-marketplace-proxy.<ns>.svc.cluster.local
  pipMirrorUrl:   http://dify-pip-proxy.<ns>.svc.cluster.local/pypi/simple/
  ignoreUvLock: true
  pluginInitTimeout: 1200
  verifyPluginSignature: false

步骤 7 — 登录

  1. 等待 Dify 实例报告其工作负载为 Ready
  2. 在浏览器中打开 Console URL;Dify 会在首次登录时提示进行 初始管理员设置(邮箱 + 密码)。
  3. 登录后,可从控制台创建更多用户。
  4. 访问 App URL 以确认已发布应用的访问是否正常(可以先从控制台发布一个快速测试应用进行验证)。

参考:Dify 实例字段

字段表单分组作用
consoleUrl访问构建界面的浏览器 URL
appUrl访问已发布应用的浏览器 URL
database.{host, port, username, name, secret, sslEnabled}数据库外部 PostgreSQL 连接。secret 保存键 password
redis.{mode, host, port, sentinels, masterName, secret, sentinelSecret, cacheDB, brokerDB, sslEnabled}Redismode = standalonesentinel
vectorStore.{enabled, host, port, username, name, secret}向量存储pgvector
storage.{type, storageClass, size, endpoint, apiBucket, pluginBucket, s3Secret, region, s3PathStyle}存储type = PVCS3
httpRoute.{gatewayName, gatewayNamespace, sectionName, hostnames}HTTP RouteGateway API 暴露;如果使用 NodePort,则省略
proxy.{marketplace, marketplaceURL, pipMirrorUrl, ignoreUvLock, pluginInitTimeout, verifyPluginSignature}高级 — Plugin proxy受限网络下的插件安装

Secret 键约定:

Secret 字段Secret 必须包含的键
database.secret / redis.secret / redis.sentinelSecret / vectorStore.secretpassword
storage.s3SecretaccessKey, secretKey