基于Compose的Dify进阶操作

@

本教程适用于Compose搭建的Dify,完成后期的一些进阶操作,例如修改知识库上传文件大小限制、自定义前端界面样式、增加工作空间等操作

常见问题

官网:

本地部署初始化后,密码错误如何重置?

  • 使用 docker compose 方式部署,可执行以下命令进行重置
docker exec -it docker-api-1 flask reset-password
  • 输入账户 email 以及两次新密码即可。

部署后如何升级版本?

  • 如果是通过镜像启动,请重新拉取最新镜像完成升级。

本地部署版,如何更改空间的名称?

  • 在数据库 tenants 表里修改。具体方式参考下面的创建工作空间

如果发生数据库迁移,需要备份哪些东西?

  • 需要备份数据库、配置的存储以及向量数据库数据,若为 docker compose 方式部署,可直接备份 dify/docker/volumes 目录下所有数据内容。
root@huhy:~# ls dify/docker/volumes/
app  certbot  db  myscale  oceanbase  opensearch  plugin_daemon  redis  sandbox  weaviate

本地部署版如何解决知识库文档上传的大小限制和数量限制。

/root/dify-main/docker/.env
# 修改为100M,默认15M
NGINX_CLIENT_MAX_BODY_SIZE=100M

# 上传文件大小限制,默认15M,调整为100
UPLOAD_FILE_SIZE_LIMIT=100

# 每次上传文件数上限,默认5个,调整50
UPLOAD_FILE_BATCH_LIMIT=50

在这里插入图片描述

部署客户端聊天界面

GitHub官网

用于创建一个对话的客户端应用,调用服务端的应用地址

  • 下载文件后上传
    在这里插入图片描述
unzip webapp-conversation-main
cd webapp-conversation-main/
  • 在当前目录下创建一个名为的文件.env.local,并从中复制内容.env.example
cp .env.example .env.local
  • 在管理端获取所需的三个地址

在这里插入图片描述

  • 创建APP_KEY

在这里插入图片描述

root@huhy:~/webapp-conversation-main# cat .env.local
NEXT_PUBLIC_APP_ID='fbdfee97-7ed3-4c99-9387-55b36b366e67'
NEXT_PUBLIC_APP_KEY='app-9CVGKyFtFIbNNVxpoMbH5QUh'
NEXT_PUBLIC_API_URL='http://192.168.200.160/v1'
  • 修改index文件
root@huhy:~/webapp-conversation-main# cat config/index.ts
import type { AppInfo } from '@/types/app'
export const APP_ID = `${process.env.NEXT_PUBLIC_APP_ID}`
export const API_KEY = `${process.env.NEXT_PUBLIC_APP_KEY}`
export const API_URL = `${process.env.NEXT_PUBLIC_API_URL}`
export const APP_INFO: AppInfo = {
  title: 'huhy',
  description: 'description',
  copyright: 'copyright',
  privacy_policy: '',
  default_language: 'zh-Hans'
}

export const isShowPrompt = true
export const promptTemplate = 'I want you to act as a javascript console.' #描述对话前的提示词

export const API_PREFIX = '/api'

export const LOCALE_COOKIE_NAME = 'locale'

export const DEFAULT_VALUE_MAX_LEN = 48
  • 有两种方式构建使用,这里使用docker
docker build . -t difyv1/webapp-conversation:latest
docker run -itd -p 3000:3000 difyv1/webapp-conversation:latest
  • 使用浏览器打开http://localhost:3000

在这里插入图片描述

在这里插入图片描述

自定义前端界面

注:不同版本在容器里面的路径不一样,需要对应查找

进入容器docker-web-1

docker exec -it docker-web-1  sh
  • 左上角logo图片替换: logo-site.png
/app/web/public/logo $ ls
logo-embedded-chat-avatar.png  logo-embedded-chat-header.png  logo-site-dark.png             logo-site.png
/app/web/public/logo $
  • 站点图标替换:favicon.ico
/app/web/public $ ls
embed.js            embed.min.js        favicon.ico         logo                pdf.worker.min.mjs  screenshots         vs
/app/web/public $
  • 首页登录的背景图片替换:background.d3434daa.png
/app/web/.next/static/media $ ls background.d3434daa.png
background.d3434daa.png
/app/web/.next/static/media $ pwd

替换后重启容器即可生效

docker restart docker-web-1  

定制化前端镜像

上面对容器的镜像都只是临时性的,删除容器就会丢失配置,如果需要长期进行使用的话可以自定义构建前端镜像

  • 进入web目录下
/root/dify-main/web
  • 该目录与上述容器的前端目录/app/web一致,本地修改后重新构建镜像
docker build . -t dify-web-huhy
root@huhy:~/dify-main/web# docker images | grep huhy
dify-web-huhy               latest      59659c1b5b4c   4 minutes ago   436MB
  • 启动该镜像:如果后端应用不在本地则修改URL地址
docker run -it -p 3000:3000 -e CONSOLE_URL=http://127.0.0.1:5001 -e APP_URL=http://127.0.0.1:5001 dify-web-huhy
root@huhy:~/dify-main/web# docker run -it -p 3000:3000 -e CONSOLE_URL=http://127.0.0.1:5001 -e APP_URL=http://127.0.0.1:5001 dify-web-huhy
                        -------------

__/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____
 _\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___
  _\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__
   _\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___
    _\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____
     _\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________
      _\/\\\_____________\/\\\_____________\/\\\___/\\\/___________
       _\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_
        _\///______________\///______________\///__\///////////////__


                          Runtime Edition

        PM2 is a Production Process Manager for Node.js applications
                     with a built-in Load Balancer.

                Start and Daemonize any application:
                $ pm2 start app.js

                Load Balance 4 instances of api.js:
                $ pm2 start api.js -i 4

                Monitor in production:
                $ pm2 monitor

                Make pm2 auto-boot at server restart:
                $ pm2 startup

                To go further checkout:
                http://pm2.io/


                        -------------

pm2 launched in no-daemon mode (you can add DEBUG="*" env variable to get more messages)
2025-03-10T07:14:20: PM2 log: Launching in no daemon mode
2025-03-10T07:14:20: PM2 log: [PM2][WARN] Applications dify-web not running, starting...
2025-03-10T07:14:20: PM2 log: App [dify-web:0] starting in -cluster mode-
2025-03-10T07:14:20: PM2 log: App [dify-web:0] online
2025-03-10T07:14:20: PM2 log: App [dify-web:1] starting in -cluster mode-
2025-03-10T07:14:20: PM2 log: App [dify-web:1] online
2025-03-10T07:14:20: PM2 log: [PM2] App [dify-web] launched (2 instances)
2025-03-10T07:14:20: PM2 log: ┌────┬─────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name        │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├────┼─────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ dify-web    │ default     │ 0.15.3  │ cluster │ 18       │ 0s     │ 0    │ online    │ 0%       │ 48.9mb   │ und… │ disabled │
│ 1  │ dify-web    │ default     │ 0.15.3  │ cluster │ 25       │ 0s     │ 0    │ online    │ 0%       │ 46.0mb   │ und… │ disabled │
└────┴─────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
2025-03-10T07:14:20: PM2 log: [--no-daemon] Continue to stream logs
2025-03-10T07:14:20: PM2 log: [--no-daemon] Exit on target PM2 exit pid=7
07:14:21 0|dify-web  |   ▲ Next.js 14.2.17
07:14:21 0|dify-web  |   - Local:        http://4616bfe78e8d:3000
07:14:21 0|dify-web  |   - Network:      http://172.17.0.2:3000
07:14:21 0|dify-web  |  ✓ Starting...
07:14:21 1|dify-web  |   ▲ Next.js 14.2.17
07:14:21 1|dify-web  |   - Local:        http://4616bfe78e8d:3000
07:14:21 1|dify-web  |   - Network:      http://172.17.0.2:3000
07:14:21 1|dify-web  |  ✓ Starting...
07:14:21 0|dify-web  |  ✓ Ready in 113ms
07:14:21 1|dify-web  |  ✓ Ready in 112ms

创建工作空间

Dify的开源社区版本默认是只有一个工作空间的,不能界面进行添加,可以手动从数据库中进行添加

  • 在api容器中生成公钥和私钥
docker exec -it docker-api-1 sh

cd /tmp/
openssl genrsa -out private.pem 2048
openssl rsa -pubout -in private.pem -out public.pem
# cat public.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA26RDlHBfhdO99hSFcGx8
fYVTwQSIpfTxGEUT7SCrFHh8AHgjkj2xvMnxU1ZsuBiPrL3XNEH1ZwTc++blJ9OK
2ONOTyaUN93CTceJ6FAfONjCQ7CNaJiB7pZzMa9CXLIQgCo2goAuNM12bV0qcqW/
cU4zwObOjutNtbLQj9bvaCRrzsux5Fnxhsv5IutpZlaCG7idw8I1okoiHprAb6L0
kQHchiBvISkDdevrrga81fULK0blJ109srOOWU3fD2UWF3/G0nbPoR84Sk8rurxP
h670y+g0S2TZ9DNtBZkYEiMdlLx3gb6MxKPXMDmokG8sZBHzoHyjkilG60ddCljm
LwIDAQAB
-----END PUBLIC KEY-----
  • 进入数据库容器(dify使用postgre数据库)
docker exec -it docker-db-1 sh

psql -U postgres -d dify
  • 插入工作空间记录,名称为dify-huhy,注意替换公钥
INSERT INTO "public"."tenants" ("name", "encrypt_public_key", "plan", "status") VALUES ('dify-huhy', '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA26RDlHBfhdO99hSFcGx8
fYVTwQSIpfTxGEUT7SCrFHh8AHgjkj2xvMnxU1ZsuBiPrL3XNEH1ZwTc++blJ9OK
2ONOTyaUN93CTceJ6FAfONjCQ7CNaJiB7pZzMa9CXLIQgCo2goAuNM12bV0qcqW/
cU4zwObOjutNtbLQj9bvaCRrzsux5Fnxhsv5IutpZlaCG7idw8I1okoiHprAb6L0
kQHchiBvISkDdevrrga81fULK0blJ109srOOWU3fD2UWF3/G0nbPoR84Sk8rurxP
h670y+g0S2TZ9DNtBZkYEiMdlLx3gb6MxKPXMDmokG8sZBHzoHyjkilG60ddCljm
LwIDAQAB
-----END PUBLIC KEY-----', 'basic', 'normal');
  • 查询dify-huhy工作空间的id
SELECT id FROM tenants WHERE name = 'dify-huhy';
dify=# SELECT id FROM tenants WHERE name = 'dify-huhy';
                  id
--------------------------------------
 b05d104f-85d7-41f7-b779-b724d0215455
(1 row)
  • 查询dify用户的id,注意在界面提前创建好
SELECT "id" FROM "accounts" where name ='huhy';
dify=# SELECT "id" FROM "accounts" where name ='huhy';
                  id
--------------------------------------
 b12265a9-6191-42c3-8588-e6768f833276
(1 row)
  • 将该用户和工作空间绑定,注意tenant_id为工作空间id,account_id为用户id
INSERT INTO "public"."tenant_account_joins" ("tenant_id", "account_id", "role", "invited_by", "current") VALUES ('b05d104f-85d7-41f7-b779-b724d0215455','b12265a9-6191-42c3-8588-e6768f833276', 'admin', NULL, 't');
dify=# INSERT INTO "public"."tenant_account_joins" ("tenant_id", "account_id", "role", "invited_by", "current") VALUES ('b05d104f-85d7-41f7-b779-b724d0215455','b12265a9-6191-42c3-8588-e6768f833276', 'admin', NULL, 't');
INSERT 0 1
  • 再次进入api容器,在/app/api/storage/privkeys目录下面创建工作空间,名称为该空间的数据库id,将私钥拷贝到目录下
docker exec -it docker-api-1 sh
cd /app/api/storage/privkeys
mkdir -p b05d104f-85d7-41f7-b779-b724d0215455
cp /tmp/private.pem b05d104f-85d7-41f7-b779-b724d0215455/private.pem
  • 浏览器界面刷新即可查看到手动添加的工作空间
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 一键替换脚本:适用dify版本(v1.11.4),上面手动测试为旧版本,唯一区别是数据库容器名称不一致
#!/bin/bash

# 创建工作空间一键脚本
# 使用方法: ./create_workspace.sh <workspace_name> <admin_username>

set -e  # 出错时退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 检查参数
if [ $# -lt 2 ]; then
    echo -e "${RED}使用方法: $0 <工作空间名称> <管理员用户名>${NC}"
    echo "示例: $0 dify-huhy huhy"
    exit 1
fi

WORKSPACE_NAME="$1"
ADMIN_USERNAME="$2"

echo -e "${GREEN}开始创建工作空间: ${WORKSPACE_NAME}${NC}"
echo -e "${YELLOW}管理员用户: ${ADMIN_USERNAME}${NC}"
echo "=========================================="

# 生成RSA密钥对
echo "1. 生成RSA密钥对..."
docker exec docker-api-1 sh -c "
    cd /tmp/ && \
    openssl genrsa -out private.pem 2048 && \
    openssl rsa -pubout -in private.pem -out public.pem
"

# 获取公钥
echo "2. 获取公钥内容..."
PUBLIC_KEY=$(docker exec docker-api-1 cat /tmp/public.pem)
echo "公钥已生成"

# 替换公钥中的单引号(PostgreSQL需要)
ESCAPED_PUBLIC_KEY=$(echo "$PUBLIC_KEY" | sed "s/'/''/g")

# 插入工作空间记录
echo "3. 在数据库中创建工作空间记录..."
INSERT_TENANT_SQL="INSERT INTO \"public\".\"tenants\" (\"name\", \"encrypt_public_key\", \"plan\", \"status\") VALUES ('$WORKSPACE_NAME', '${ESCAPED_PUBLIC_KEY}', 'basic', 'normal');"

docker exec docker-db_postgres-1 psql -U postgres -d dify -c "$INSERT_TENANT_SQL"

# 查询工作空间ID
echo "4. 查询工作空间ID..."
TENANT_ID=$(docker exec docker-db_postgres-1 psql -U postgres -d dify -t -c "SELECT id FROM tenants WHERE name = '$WORKSPACE_NAME';" | tr -d '[:space:]')

if [ -z "$TENANT_ID" ]; then
    echo -e "${RED}错误: 无法获取工作空间ID${NC}"
    exit 1
fi

echo "工作空间ID: $TENANT_ID"

# 查询用户ID
echo "5. 查询用户ID..."
USER_ID=$(docker exec docker-db_postgres-1 psql -U postgres -d dify -t -c "SELECT \"id\" FROM \"accounts\" WHERE name ='$ADMIN_USERNAME';" | tr -d '[:space:]')

if [ -z "$USER_ID" ]; then
    echo -e "${RED}错误: 用户 '$ADMIN_USERNAME' 不存在,请先在Dify界面创建该用户${NC}"
    exit 1
fi

echo "用户ID: $USER_ID"

# 绑定用户和工作空间
echo "6. 绑定用户到工作空间..."
INSERT_JOIN_SQL="INSERT INTO \"public\".\"tenant_account_joins\" (\"tenant_id\", \"account_id\", \"role\", \"invited_by\", \"current\") VALUES ('$TENANT_ID','$USER_ID', 'admin', NULL, 't');"

docker exec docker-db_postgres-1 psql -U postgres -d dify -c "$INSERT_JOIN_SQL"

# 创建私钥目录并复制私钥
echo "7. 创建私钥目录..."
docker exec docker-api-1 mkdir -p "/app/api/storage/privkeys/$TENANT_ID"

echo "8. 复制私钥文件..."
docker exec docker-api-1 cp /tmp/private.pem "/app/api/storage/privkeys/$TENANT_ID/private.pem"

# 清理临时文件(可选)
echo "9. 清理临时文件..."
docker exec docker-api-1 rm -f /tmp/private.pem /tmp/public.pem

echo -e "${GREEN}==========================================${NC}"
echo -e "${GREEN}工作空间创建完成!${NC}"
echo -e "${GREEN}工作空间名称: ${WORKSPACE_NAME}${NC}"
echo -e "${GREEN}工作空间ID: ${TENANT_ID}${NC}"
echo -e "${GREEN}管理员: ${ADMIN_USERNAME}${NC}"
echo ""
echo -e "${YELLOW}现在你可以在Dify界面切换到新的工作空间了${NC}"
  • 使用示例
root@huhy:~# bash create_workspace.sh huhy_test huhy
开始创建工作空间: huhy_test
管理员用户: huhy
==========================================
1. 生成RSA密钥对...
writing RSA key
2. 获取公钥内容...
公钥已生成
3. 在数据库中创建工作空间记录...
INSERT 0 1
4. 查询工作空间ID...
工作空间ID: 1d3f03dc-99aa-4f42-814d-be1725ed21b9
5. 查询用户ID...
用户ID: 0d5013bf-a0d0-4cab-a019-bcb2d370b30d
6. 绑定用户到工作空间...
INSERT 0 1
7. 创建私钥目录...
8. 复制私钥文件...
9. 清理临时文件...
==========================================
工作空间创建完成!
工作空间名称: huhy_test
工作空间ID: 1d3f03dc-99aa-4f42-814d-be1725ed21b9
管理员: huhy

现在你可以在Dify界面切换到新的工作空间了

模型Toekn监控

Dify本身的模型监控能力较弱,可配置grafana对dify的pgsql数据库进行模型监控

  • 将数据库端口暴露
vim docker-compose.yaml
  db_postgres:
    image: postgres:15-alpine
    profiles:
      - postgresql
    restart: always
    ports:   # 添加
      - "5432:5432"  # 添加
  • 重启数据库
docker compose up -d db_postgres

搭建grafana

mkdir /root/grafana && cd /root/grafana
vi docker-compose.yml
services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=365d'     # 保留 365 天(1年)
    restart: unless-stopped

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ALLOW_EMBEDDING=true
      - GF_SECURITY_COOKIE_SAMESITE=disabled
    volumes:
      - ./grafana-data:/var/lib/grafana
    restart: unless-stopped
  • 配置持久化目录
mkdir -p prometheus-data
chown -R 65534:65534 prometheus-data

mkdir -p grafana-data
chown -R 472:472 grafana-data

启动服务:

docker compose up -d
  1. 访问 http://ip:3000
  2. 默认账号密码:admin / admin(首次登录需修改密码,设为 admin123)
  3. 添加 grafana-postgresql-datasource 数据源:
    • 菜单:Configuration → Data Sources → Add data source
    • 选择 grafana-postgresql-datasource
    • URL:http://ip:5432
    • 数据库名:dify(默认)
    • username:postgres(默认)
    • password:difyai123456(默认)
    • 点击 Save & test
  • 修改中文
    在这里插入图片描述
  • 替换json模板的数据源id
    在这里插入图片描述
dashboard-Dify-monitor.json
  • 导入模板
    在这里插入图片描述
  • 监控页面
    在这里插入图片描述
    在这里插入图片描述

Dify升级

官网

低版本升级到v1.10.1

Docker Compose 部署

  • 升级前需要执行的操作
    从此版本开始1.10.1,Dify API 镜像将以非 root 用户(UID 1001)身份运行,以提高安全性。
    如果您使用的是本地文件系统存储(社区部署的默认设置),则必须更新主机上已挂载存储目录的所有权,否则容器将无法读取/写入文件。

受影响的服务:

api
worker

受影响的主机目录:

./volumes/app/storage→ 挂载到/app/api/storage
  • 在重启新版本之前,必须执行以下操作:
[root@localhost docker]# pwd
/root/dify/docker
docker compose down
sudo chown -R 1001:1001 ./volumes/app/storage
docker compose up -d
  • 完成此次一次性迁移后,Dify 将以新的非 root 用户模型正常运行。
    备份您自定义的 docker-compose YAML 文件(可选)
[root@localhost docker]# pwd
/root/dify/docker
cp docker-compose.yaml docker-compose.yaml.$(date +%s).bak
  • 从主分支获取最新代码
[root@localhost dify]# pwd
/root/dify
git checkout main
git pull origin main
  • 停止服务。请在 Docker 目录中执行此操作。
[root@localhost docker]# pwd
/root/dify/docker
docker compose down
  • 备份数据
tar -cvf volumes-$(date +%s).tgz volumes
  • 升级服务
docker compose up -d
  • 如果您遇到如下错误,请参考以下说明。
2025/11/26 11:37:57 /app/internal/db/pg/pg.go:30
[error] failed to initialize database, got error failed to connect to `host=db_postgres user=postgres database=dify_plugin`: hostname resolving error (lookup db_postgres on 127.0.0.11:53: server misbehaving)

2025/11/26 11:37:57 /app/internal/db/pg/pg.go:34
[error] failed to initialize database, got error failed to connect to `host=db_postgres user=postgres database=postgres`: hostname resolving error (lookup db_postgres on 127.0.0.11:53: server misbehaving)
2025/11/26 11:37:57 init.go:99: [PANIC]failed to init dify plugin db: failed to connect to `host=db_postgres user=postgres database=postgres`: hostname resolving error (lookup db_postgres on 127.0.0.11:53: server misbehaving)
panic: [PANIC]failed to init dify plugin db: failed to connect to `host=db_postgres user=postgres database=postgres`: hostname resolving error (lookup db_postgres on 127.0.0.11:53: server misbehaving)

请改用以下命令。

docker compose --profile postgresql up -d

注:如果git拉取不了还可以手动从GitHub下载,然后替换volume下的所有存储数据,重新启动即可

posted @ 2025-03-14 09:59  huhy  阅读(2096)  评论(0)    收藏  举报  来源
--> --> /*文章评论*/