Dify:自建AI工作流平台
Module:
Categories:
Dify 是一个生成式 AI 应用创新引擎,开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力,帮助用户轻松构建和运营生成式 AI 原生应用。
Pigsty 提供对自建 Dify 的支持,您可以一键拉起 Dify ,并将关键状态保存于外部由 Pigsty 管理的 PostgreSQL ,并使用同一个 PG 中的 pgvector 作为向量数据库,进一步简化版部署。
快速上手
curl -fsSL https://repo.pigsty.io/get | bash; cd ~/pigsty
./bootstrap # 安装 Pigsty 依赖
./configure -c app/dify # 使用 Dify 配置模板 (请在这一步修改生成配置文件 pigsty.yml 中的各种密码!)
./install.yml # 安装 Pigsty
./docker.yml # 安装 Docker 模块
./app.yml # 拉起 Dify
Dify 默认监听于 5001
端口,你可以通过浏览器访问 http://<ip>:5001
,并设置初始用户与密码。
请注意,Odoo 无状态部分使用 Docker 拉起,然而中国大陆 DockerHub 被墙, 你可能需要参考教程 来配置 镜像站或代理服务器 方可顺利完成最后一步。 在 Pigsty 商业版 中,我们可以帮您丝滑解决这个问题。
请注意,Redis 在 Dify 中作为“缓存”使用,因此默认同样使用容器拉起。但您同样可以使用容器外部由 Pigsty 所托管的 Redis 作为 Dify 的缓存
配置文件
在 conf/app/dify.yml
中有一个模板配置文件,定义了单机 Dify 所需的资源。
在 configure
之后,您应该根据自己的实际需求,修改这里的密码类参数。请注意修改密码务必匹配:例如你如果在 pg_users
中修改了 dify
数据库用户的密码,
那么也同样要修改 all.children.odoo.vars.apps.<dify>.conf.PG_PASSWORD
参数,以确保 Odoo 与 PostgreSQL 数据库的连接正常。
这里需要特别注意的是,请务必使用 openssl rand -base64 42
生成一个你自己的随机密钥,替换 SECRET_KEY
,并相应更改其他密码类参数。
all:
children:
# the dify application (default username & password: admin/admin)
dify:
hosts: { 10.10.10.10: {} }
vars:
app: dify # specify app name to be installed (in the apps)
apps: # define all applications
dify: # app name, should have corresponding ~/app/dify folder
conf: # override /opt/dify/.env config file
# A secret key for signing and encryption, gen with `openssl rand -base64 42` (CHANGE PASSWORD!)
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
DB_USERNAME: dify
DB_PASSWORD: difyai123456
DB_HOST: 10.10.10.10
DB_PORT: 5432
DB_DATABASE: dify
VECTOR_STORE: pgvector
PGVECTOR_HOST: 10.10.10.10
PGVECTOR_PORT: 5432
PGVECTOR_USER: dify
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
PGVECTOR_MIN_CONNECTION: 2
PGVECTOR_MAX_CONNECTION: 10
NGINX_SERVER_NAME: localhost
DIFY_PORT: 5001 # expose DIFY nginx service with port 5001 by default
#STORAGE_TYPE: s3
#S3_ENDPOINT: 'https://sss.pigsty'
#S3_BUCKET_NAME: 'dify'
#S3_ACCESS_KEY: 'dify'
#S3_SECRET_KEY: 'S3User.Dify'
#S3_REGION: 'us-east-1'
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_users:
- { name: dify ,password: difyai123456 ,pgbouncer: true ,roles: [ dbrole_admin ] ,superuser: true ,comment: dify superuser }
pg_databases:
- { name: dify ,owner: dify ,revokeconn: true ,comment: dify main database }
pg_hba_rules:
- { user: dify ,db: all ,addr: 172.17.0.0/16 ,auth: pwd ,title: 'allow dify access from local docker network' }
- { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }
etcd: { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }
vars: # global variables
version: v3.3.0 # pigsty version string
admin_ip: 10.10.10.10 # admin node ip address
region: default # upstream mirror region: default|china|europe
node_tune: oltp # node tuning specs: oltp,olap,tiny,crit
pg_conf: oltp.yml # pgsql tuning specs: {oltp,olap,tiny,crit}.yml
docker_enabled: true # enable docker on app group
#docker_registry_mirrors: ["https://docker.m.daocloud.io"] # use dao cloud mirror in mainland china
proxy_env: # global proxy env when downloading packages & pull docker images
no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.tsinghua.edu.cn"
#http_proxy: 127.0.0.1:12345 # add your proxy env here for downloading packages or pull images
#https_proxy: 127.0.0.1:12345 # usually the proxy is format as http://user:pass@proxy.xxx.com
#all_proxy: 127.0.0.1:12345
infra_portal: # domain names and upstream servers
home : { domain: h.pigsty }
grafana : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
prometheus : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
blackbox : { endpoint: "${admin_ip}:9115" }
loki : { endpoint: "${admin_ip}:3100" }
minio : { domain: m.pigsty ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
dify: { domain: dify.pigsty ,endpoint: "10.10.10.10:5001" ,websocket: true }
# setup your own domain name here ^^^, or use default domain name, or ip + 5001 port direct access
# certbot --nginx --agree-tos --email your@email.com -n -d dify.your.domain # replace with your email & dify domain
#----------------------------------#
# Credential: CHANGE THESE PASSWORDS
#----------------------------------#
#grafana_admin_username: admin
grafana_admin_password: pigsty
#pg_admin_username: dbuser_dba
pg_admin_password: DBUser.DBA
#pg_monitor_username: dbuser_monitor
pg_monitor_password: DBUser.Monitor
#pg_replication_username: replicator
pg_replication_password: DBUser.Replicator
#patroni_username: postgres
patroni_password: Patroni.API
#haproxy_admin_username: admin
haproxy_admin_password: pigsty
#minio_access_key: minioadmin
minio_secret_key: minioadmin # minio root secret key, `minioadmin` by default
# use minio as supabase file storage, single node single driver mode for demonstration purpose
minio_buckets: [ { name: pgsql }, { name: supa } ]
minio_users:
- { access_key: dba , secret_key: S3User.DBA, policy: consoleAdmin }
- { access_key: pgbackrest , secret_key: S3User.Backup ,policy: readwrite }
- { access_key: dify , secret_key: S3User.Dify ,policy: readwrite } # <----- Change These Too!
minio_endpoint: https://sss.pigsty:9000 # explicit overwrite minio endpoint with haproxy port
node_etc_hosts: ["10.10.10.10 sss.pigsty"] # domain name to access minio from all nodes (required)
# use minio as default backup repo for PostgreSQL
pgbackrest_method: minio # pgbackrest repo method: local,minio,[user-defined...]
pgbackrest_repo: # pgbackrest repo: https://pgbackrest.org/configuration.html#section-repository
local: # default pgbackrest repo with local posix fs
path: /pg/backup # local backup directory, `/pg/backup` by default
retention_full_type: count # retention full backups by count
retention_full: 2 # keep 2, at most 3 full backup when using local fs repo
minio: # optional minio repo for pgbackrest
type: s3 # minio is s3-compatible, so s3 is used
s3_endpoint: sss.pigsty # minio endpoint domain name, `sss.pigsty` by default
s3_region: us-east-1 # minio region, us-east-1 by default, useless for minio
s3_bucket: pgsql # minio bucket name, `pgsql` by default
s3_key: pgbackrest # minio user access key for pgbackrest
s3_key_secret: S3User.Backup # minio user secret key for pgbackrest
s3_uri_style: path # use path style uri for minio rather than host style
path: /pgbackrest # minio backup path, default is `/pgbackrest`
storage_port: 9000 # minio port, 9000 by default
storage_ca_file: /pg/cert/ca.crt # minio ca file path, `/pg/cert/ca.crt` by default
bundle: y # bundle small files into a single file
cipher_type: aes-256-cbc # enable AES encryption for remote backup repo
cipher_pass: pgBackRest # AES encryption password, default is 'pgBackRest'
retention_full_type: time # retention full backup by time on minio repo
retention_full: 14 # keep full backup for last 14 days
repo_modules: infra,node,pgsql,docker
repo_packages: [ node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, docker ]
repo_extra_packages: [ pg17-main ]
pg_version: 17
Pigsty的准备工作
我们用 单机安装 的 Pigsty 为例,假设你有一台 IP 地址为 10.10.10.10
的机器,已经 安装好了单机 Pigsty。
当然,我们需要在 Pigsty 配置文件 pigsty.yml
中定义一下我们所需的数据库集群。
这里定义了一个名为 pg-meta
的集群,其中有一个名为 dify
的超级业务用户,
一个安装了 pgvector
扩展插件的数据库 dify
,以及一条特定的防火墙规则,允许用户通过密码从任何地方访问数据库(你也可以将其限制为docker的网段 172.0.0.0/8
之类更精确的范围)。
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_users:
- { name: dify ,password: difyai123456 ,pgbouncer: true ,roles: [ dbrole_admin ] ,superuser: true ,comment: dify superuser }
pg_databases:
- { name: dify ,owner: dify ,revokeconn: true ,comment: dify main database }
pg_hba_rules:
- { user: dify ,db: all ,addr: 172.17.0.0/16 ,auth: pwd ,title: 'allow dify access from local docker network' }
- { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
这里出于演示目的,我们全部使用单实例配置,你可以参考 Pigsty 文档部署 高可用 的 PG 集群。
bin/pgsql-add pg-meta # create the dify database cluster
当然,您也可以在现有的 PostgreSQL 集群,例如 pg-meta
上新定义业务用户与业务数据库,并通过以下命令创建:
bin/pgsql-user pg-meta dify # create dify biz user
bin/pgsql-db pg-meta dify # create dify biz database
您应该可以通过以下的连接串,访问到 PostgreSQL 与 Redis,当然连接信息请根据实际情况进行修改。
psql postgres://dify:difyai123456@10.10.10.10:5432/dify -c 'SELECT 1'
当你确认这个连接串可用后,大功告成,你可以开始部署 Dify 了。
这里出于演示方便的原因,使用IP直连的土办法,如果是多节点的高可用 PG 集群,请参考 接入 一节。
当然,上面的部分是假设你已经是 Pigsty 用户,了解如何部署 PostgreSQL 与 Redis 集群。你可以直接跳过下一节,查看 Dify 如何配置。
从零开始的一些说明
如果您已经了解如何配置使用 Pigsty,可以略过本节。
从零安装 Pigsty 需要 准备 一台符合要求的机器节点: Linux / x86_64,静态 IP,使用带有免密 sudo
权限的用户,执行以下命令:
curl -fsSL https://repo.pigsty.io/get | bash
然后依次完成以下步骤:
cd ~/pigsty # 下载源码包解压后进入 Pigsty 源码目录,完成后续 准备、配置、安装 三个步骤
./bootstrap # 【可选项】用于确保 Ansible 正常安装,如果 /tmp/pkg.tgz 离线包则使用它
./configure # 【可选项】执行环境检测,并生成相应的推荐配置文件,如果知道如何配置可以跳过
# …… 这里请修改自动生成的配置 pigsty.yml ,将上面的集群定义填入 all.children 部分内
./install.yml # 根据生成的配置文件开始在当前节点上执行安装,使用离线安装包大概需要10分钟完成
您应当将上面的 PostgreSQL 集群与 Redis 集群定义填入 pigsty.yml
文件中,然后执行 install.yml
完成安装。
Redis安装问题
Pigsty 默认不会安装 Redis,所以您需要使用 redis.yml
剧本显式完成 Redis 安装:
./redis.yml
Docker安装问题
Pigsty 默认不会在当前节点安装 Docker,所以您需要使用 docker.yml
剧本安装 Docker。
./docker.yml
Docker Hub 被墙问题
请注意,对于中国大陆用户来说,Docker Hub 与各镜像站点目前出于封锁状态,需要 “科学上网” 才能拉取 Dify 所需的镜像,您可以考虑 docker save|load
,或者为 Docker Daemon 配置代理。
要为 Docker Daemon 配置代理,您需要在 proxy_env
中指定 http_proxy
与 https_proxy
环境变量,该参数会在 docker_config
任务中被写入 /etc/docker/daemon.json
中:
{
"proxies": {
"http-proxy": "http://192.168.x.x:8118",
"https-proxy": "http://192.168.x.x:8118",
"no-proxy": "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.myqcloud.com,*.tsinghua.edu.cn"
}
}
当然您也可以直接在配置文件中填入您的 HTTP/HTTPS 代理地址,并使用 systemctl restart docker
重启生效。
$ docker compose pull
[+] Pulling 5/5
✔ worker Skipped - Image is already being pulled by api
✔ web Pulled
✔ api Pulled
✔ ssrf_proxy Pulled
✔ nginx Pulled
配置代理后,镜像都可以成功拉取了。当然您也可以使用其他可用的镜像站点,例如 quay.io 等。
Dify的配置工作
Dify 的配置参数一如往常地放在 .env
文件中,内容如下所示:
所有参数都顾名思义,已经填入了在 Pigsty默认沙箱环境 中可以直接工作的默认值,数据库连接信息请根据您的真实配置,与上面 PG / Redis 集群配置保持一致即可。
我们建议你随便改一下这个 SECRET_KEY
字段,可以使用 openssl rand -base64 42
生成一个强密钥。
# meta parameter
DIFY_PORT=8001 # expose dify nginx service with port 8001 by default
LOG_LEVEL=INFO # The log level for the application. Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
SECRET_KEY=sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U # A secret key for signing and encryption, gen with `openssl rand -base64 42`
# postgres credential
PG_USERNAME=dbuser_dify
PG_PASSWORD=DBUser.Dify
PG_HOST=10.10.10.10
PG_PORT=5432
PG_DATABASE=dify
# redis credential
REDIS_HOST=10.10.10.10
REDIS_PORT=6379
REDIS_USERNAME=''
REDIS_PASSWORD=redis.dify
# minio/s3 [OPTIONAL] when STORAGE_TYPE=s3
STORAGE_TYPE=local
S3_ENDPOINT='https://sss.pigsty'
S3_BUCKET_NAME='infra'
S3_ACCESS_KEY='dba'
S3_SECRET_KEY='S3User.DBA'
S3_REGION='us-east-1'
填好连接信息后,我们就可以使用 Docker Compose 拉起 Dify 服务了:
cd pigsty/app/dify && make up
使用Nginx暴露Web服务
Dify 的 Docker Compose 模板里面已经包含了一个 Nginx Server,占据了宿主机的 80 端口。如果你的这台机器就是拿来专门跑 Dify 的那没问题。如果你用的是 Pigsty 单机安装,那么这台宿主机上的 80 端口已经被 Pigsty 部署的 Nginx Web Portal 占据了。
所以,Pigsty 提供的模板中,DIFY_PORT
默认使用了 8001
,并通过宿主机上 Pigsty 部署的 Nginx 转发至此端口。当然我们也提供选项B,你也可以直接在 /etc/nginx/conf.d/dify.conf
里使用样例配置,直接指向 Dify 的 web
与 api
端口。
在 pigsty.yml
配置文件中的 infra_portal
参数中新增一行 Dify 的配置
infra_portal: # domain names and upstream servers
home : { domain: h.pigsty }
grafana : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
prometheus : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
blackbox : { endpoint: "${admin_ip}:9115" }
loki : { endpoint: "${admin_ip}:3100" }
dify : { domain: dify.pigsty ,endpoint: "10.10.10.10:8001", websocket: true }
执行以下剧本,重新生成 Nginx 配置、证书并应用:
./infra.yml -t nginx
当然如果要通过域名访问,你要把自己的域名 dify.pigsty
添加到域名服务器,或者简单地写入:/etc/hosts
或 C:\Windows\System32\drivers\etc\hosts
之类的静态域名解析文件。
然后,你就可以从浏览器中,通过 http://dify.pigsty 访问 Dify IDE 了。