diff --git a/frameworks/Dify/1.14.2/Dockerfile b/frameworks/Dify/1.14.2/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..af621836e44c0e1ef65bd09aa4b094d2d234321c --- /dev/null +++ b/frameworks/Dify/1.14.2/Dockerfile @@ -0,0 +1,63 @@ +# syntax=docker/dockerfile:1.7 + +ARG DIFY_VERSION=1.14.2 +ARG PLUGIN_DAEMON_VERSION=0.6.1-local + + +FROM langgenius/dify-api:${DIFY_VERSION} AS dify_api +FROM langgenius/dify-web:${DIFY_VERSION} AS dify_web +FROM langgenius/dify-plugin-daemon:${PLUGIN_DAEMON_VERSION} AS plugin_daemon +FROM node:22-bookworm-slim AS node_runtime + +FROM opencloudos/opencloudos9-cuda-devel:12.8 +LABEL maintainer="stronking 363133710@qq.com" +LABEL org.opencontainers.image.source="https://gitee.com/OpenCloudOS/ai-agent-container" +LABEL org.opencontainers.image.description="Dify 1.14.2 on OpenCloudOS 9 with Python 3.11, CUDA 12.8 ,Nodejs 22" +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +ENV LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + PYTHONIOENCODING=utf-8 \ + TZ=Asia/Shanghai \ + EDITION=SELF_HOSTED \ + DEPLOY_ENV=PRODUCTION \ + FLASK_APP=app.py \ + PATH=/app/api/.venv/bin:/usr/local/bin:/usr/bin:/bin \ + NODE_ENV=production \ + PORT=3000 \ + NLTK_DATA=/usr/local/share/nltk_data \ + TIKTOKEN_CACHE_DIR=/app/api/.tiktoken_cache + +# 完整复制官方 Dify API Python Runtime,包含 Python 3.12、pip、site-packages 等 +COPY --from=dify_api /usr/local /usr/local + +# 再复制 Node.js,避免 /usr/local/bin 被 Python Runtime 覆盖 +COPY --from=node_runtime /usr/local/bin/node /usr/local/bin/node +COPY --from=node_runtime /usr/local/bin/npm /usr/local/bin/npm +COPY --from=node_runtime /usr/local/bin/npx /usr/local/bin/npx +COPY --from=node_runtime /usr/local/lib/node_modules /usr/local/lib/node_modules + +RUN mkdir -p \ + /app/api \ + /app/web-root \ + /app/plugin-daemon-root \ + /app/storage \ + /usr/local/share/nltk_data + +COPY --from=dify_api /app/api /app/api +COPY --from=dify_api /usr/local/share/nltk_data /usr/local/share/nltk_data +COPY --from=dify_api /entrypoint.sh /app/api-entrypoint.sh + +COPY --from=dify_web /app /app/web-root + +COPY --from=plugin_daemon /app /app/plugin-daemon-root + + +COPY dify-entrypoint.sh /usr/local/bin/dify-entrypoint + +RUN sed -i 's/\r$//' /usr/local/bin/dify-entrypoint /app/api-entrypoint.sh \ + && chmod +x /usr/local/bin/dify-entrypoint /app/api-entrypoint.sh + +EXPOSE 5001 3000 5002 5003 + +CMD ["/usr/local/bin/dify-entrypoint"] \ No newline at end of file diff --git a/frameworks/Dify/1.14.2/README.md b/frameworks/Dify/1.14.2/README.md new file mode 100644 index 0000000000000000000000000000000000000000..11be8bcddfbed1a1dbad4195bb5886ab2329e430 --- /dev/null +++ b/frameworks/Dify/1.14.2/README.md @@ -0,0 +1,317 @@ +# Dify on OpenCloudOS 9 + +## 基本信息 + +* **框架版本**:Dify v1.14.2 +* **基础镜像**:`opencloudos/opencloudos9-cuda-devel:12.8` +* **Python 版本**:3.11 +* **CUDA 版本**:12.8 +* **Node.js 版本**:22 +* **Plugin Daemon 版本**:`0.6.1-local` +* **镜像模式**:单镜像,多角色容器运行 + +该镜像合并了以下 Dify 组件: + +```text +api +worker +beat +web +plugin_daemon +``` + +不包含以下外部依赖: + +```text +PostgreSQL +Redis +Nginx +向量数据库 +sandbox +ssrf_proxy +``` + +## 构建 + +```bash +docker build -t oc9-dify:1.14.2 . +``` + +也可以显式指定版本: + +```bash +docker build \ + --build-arg DIFY_VERSION=1.14.2 \ + --build-arg PLUGIN_DAEMON_VERSION=0.6.1-local \ + -t oc9-dify:1.14.2 . +``` + +## 使用示例 + +查看 Python 版本: + +```bash +docker run --rm oc9-dify:1.14.2 \ + python --version +``` + +查看 Dify 后端虚拟环境 Python: + +```bash +docker run --rm --entrypoint bash oc9-dify:1.14.2 \ + -c "/app/api/.venv/bin/python --version" +``` + +查看 Node.js 版本: + +```bash +docker run --rm --entrypoint bash oc9-dify:1.14.2 \ + -c "node --version" +``` + +查看角色启动入口: + +```bash +docker run --rm oc9-dify:1.14.2 +``` + +默认启动: + +```text +ROLE=api +``` + +## 运行方式 + +该镜像通过 `ROLE` 环境变量区分启动角色。 + +### 启动 API + +```bash +docker run -d \ + --name dify-api \ + -e ROLE=api \ + -e DB_HOST= \ + -e DB_PORT=5432 \ + -e DB_USERNAME=dify \ + -e DB_PASSWORD= \ + -e DB_DATABASE=dify \ + -e REDIS_HOST= \ + -e REDIS_PORT=6379 \ + -e REDIS_PASSWORD= \ + -p 5001:5001 \ + oc9-dify:1.14.2 +``` + +### 启动 Worker + +```bash +docker run -d \ + --name dify-worker \ + -e ROLE=worker \ + -e DB_HOST= \ + -e DB_PORT=5432 \ + -e DB_USERNAME=dify \ + -e DB_PASSWORD= \ + -e DB_DATABASE=dify \ + -e REDIS_HOST= \ + -e REDIS_PORT=6379 \ + -e REDIS_PASSWORD= \ + oc9-dify:1.14.2 +``` + +### 启动 Beat + +```bash +docker run -d \ + --name dify-beat \ + -e ROLE=beat \ + -e DB_HOST= \ + -e DB_PORT=5432 \ + -e DB_USERNAME=dify \ + -e DB_PASSWORD= \ + -e DB_DATABASE=dify \ + -e REDIS_HOST= \ + -e REDIS_PORT=6379 \ + -e REDIS_PASSWORD= \ + oc9-dify:1.14.2 +``` + +### 启动 Web + +```bash +docker run -d \ + --name dify-web \ + -e ROLE=web \ + -e CONSOLE_API_URL=http://:5001 \ + -e APP_API_URL=http://:5001 \ + -p 3000:3000 \ + oc9-dify:1.14.2 +``` + +### 启动 Plugin Daemon + +```bash +docker run -d \ + --name dify-plugin-daemon \ + -e ROLE=plugin_daemon \ + -e DB_HOST= \ + -e DB_PORT=5432 \ + -e DB_USERNAME=dify \ + -e DB_PASSWORD= \ + -e DB_DATABASE=dify_plugin \ + -e DB_SSL_MODE=disable \ + -e REDIS_HOST= \ + -e REDIS_PORT=6379 \ + -e REDIS_PASSWORD= \ + -e SERVER_PORT=5002 \ + -e SERVER_KEY= \ + -e DIFY_INNER_API_URL=http://:5001 \ + -e DIFY_INNER_API_KEY= \ + -e PLUGIN_WORKING_PATH=/app/storage/cwd \ + -e PLUGIN_STORAGE_LOCAL_ROOT=/app/storage \ + -v ./volumes/plugin_daemon:/app/storage \ + -p 5002:5002 \ + -p 5003:5003 \ + oc9-dify:1.14.2 +``` + +## docker-compose 示例 + +```yaml +services: + api: + image: oc9-dify:1.14.2 + environment: + ROLE: api + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: dify + DB_PASSWORD: dify + DB_DATABASE: dify + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: redis + PLUGIN_DAEMON_URL: http://plugin_daemon:5002 + INNER_API_KEY_FOR_PLUGIN: change-this-key + ports: + - "5001:5001" + volumes: + - ./volumes/app/storage:/app/api/storage + + worker: + image: oc9-dify:1.14.2 + environment: + ROLE: worker + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: dify + DB_PASSWORD: dify + DB_DATABASE: dify + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: redis + INNER_API_KEY_FOR_PLUGIN: change-this-key + volumes: + - ./volumes/app/storage:/app/api/storage + + beat: + image: oc9-dify:1.14.2 + environment: + ROLE: beat + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: dify + DB_PASSWORD: dify + DB_DATABASE: dify + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: redis + + web: + image: oc9-dify:1.14.2 + environment: + ROLE: web + CONSOLE_API_URL: http://localhost:5001 + APP_API_URL: http://localhost:5001 + ports: + - "3000:3000" + + plugin_daemon: + image: oc9-dify:1.14.2 + environment: + ROLE: plugin_daemon + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: dify + DB_PASSWORD: dify + DB_DATABASE: dify_plugin + DB_SSL_MODE: disable + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: redis + SERVER_PORT: 5002 + SERVER_KEY: change-this-plugin-key + DIFY_INNER_API_URL: http://api:5001 + DIFY_INNER_API_KEY: change-this-key + PLUGIN_WORKING_PATH: /app/storage/cwd + PLUGIN_STORAGE_LOCAL_ROOT: /app/storage + volumes: + - ./volumes/plugin_daemon:/app/storage + ports: + - "5002:5002" + - "5003:5003" +``` + +## 已知问题 + +* 该镜像不包含 PostgreSQL、Redis、向量数据库、sandbox、ssrf_proxy,需要外部提供。 +* `api`、`worker`、`beat`、`web`、`plugin_daemon` 必须使用同一个 Dify 版本构建。 +* `plugin_daemon` 版本必须与官方 compose 对齐,Dify `1.14.2` 对应 `0.6.1-local`。 +* 插件目录 `/app/storage` 必须持久化,否则插件安装状态可能丢失。 +* Web 服务需要正确配置 `CONSOLE_API_URL` 和 `APP_API_URL`。 +* Dify 后端默认不需要 CUDA,也不依赖 torch;CUDA 主要用于你额外部署本地模型、embedding 或 rerank 服务。 +* 生产环境建议仍使用外部 Nginx 或网关统一暴露 Web/API。 + + +### Dify镜像版本与plugin_daemon版本对应 +| Dify 版本 | plugin-daemon 版本 | +| ------- | ---------------- | +| 1.11.3 | `0.5.2-local` | +| 1.11.4 | `0.5.2-local` | +| 1.12.0 | `0.5.3-local` | +| 1.12.1 | `0.5.3-local` | +| 1.13.0 | `0.5.3-local` | +| 1.13.1 | `0.5.4-local` | +| 1.13.2 | `0.5.4-local` | +| 1.13.3 | `0.5.3-local` | +| 1.14.1 | `0.6.0-local` | +| 1.14.2 | `0.6.1-local` | + + +### 版本之间真正的区别(部署角度) +| 版本 | 特征 | 是否推荐生产 | +| ------ | ----------------- | ------ | +| 1.11.3 | 插件体系稳定化开始 | 可 | +| 1.11.4 | 安全修复版 | 推荐 | +| 1.12.0 | Summary Index 大升级 | 谨慎 | +| 1.12.1 | 修复 1.12 问题 | 推荐 | +| 1.13.0 | Agent 架构升级 | 可 | +| 1.13.1 | Worker/plugin 修复 | 推荐 | +| 1.13.2 | 稳定性修复 | 推荐 | +| 1.13.3 | 1.13 最稳定版 | 强烈推荐 | +| 1.14.1 | 企业化增强 | 推荐 | +| 1.14.2 | 当前最稳定 | 最推荐 | + +## 数据库兼容性(很重要) + +1.11 ——> 1.12 风险很大 +~~~ +知识库 schema +索引 schema +~~~ +变化明显 + + +# 部署配置获取 +* OpenCloudOS: https://gitee.com/OpenCloudOS/ai-agent-container/tree/master/frameworks \ No newline at end of file diff --git a/frameworks/Dify/1.14.2/build.conf b/frameworks/Dify/1.14.2/build.conf new file mode 100644 index 0000000000000000000000000000000000000000..b09a0f318779b6411d778c0424c8d29c46d6d058 --- /dev/null +++ b/frameworks/Dify/1.14.2/build.conf @@ -0,0 +1,4 @@ +# Dify 1.14.2 [Api,Web,Plugin]on OpenCloudOS 9 (GPU) +IMAGE_NAME=oc9-dify +IMAGE_TAG=1.14.2 +GPU_TEST=false \ No newline at end of file diff --git a/frameworks/Dify/1.14.2/compose-template.yml b/frameworks/Dify/1.14.2/compose-template.yml new file mode 100644 index 0000000000000000000000000000000000000000..ed19f9155012de5fce5d30f5b1d985f29657f0bb --- /dev/null +++ b/frameworks/Dify/1.14.2/compose-template.yml @@ -0,0 +1,195 @@ +name: dify-opencloudos + +x-dify-image: &dify_image oc9-dify:1.14.2 + +x-common-env: &common_env + EDITION: SELF_HOSTED + DEPLOY_ENV: PRODUCTION + CONSOLE_API_URL: http://localhost:5001 + CONSOLE_WEB_URL: http://localhost:3000 + SERVICE_API_URL: http://localhost:5001 + APP_API_URL: http://localhost:5001 + APP_WEB_URL: http://localhost:3000 + SECRET_KEY: "change-this-to-a-long-random-secret" + + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: postgres + DB_PASSWORD: dify_postgres_password + DB_DATABASE: dify + + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_PASSWORD: dify_redis_password + CELERY_BROKER_URL: redis://:dify_redis_password@redis:6379/1 + + STORAGE_TYPE: local + STORAGE_LOCAL_PATH: /app/storage + + VECTOR_STORE: weaviate + WEAVIATE_ENDPOINT: http://weaviate:8080 + WEAVIATE_API_KEY: "" + + PLUGIN_DAEMON_URL: http://plugin_daemon:5002 + PLUGIN_DAEMON_KEY: "change-this-plugin-key" + PLUGIN_MAX_PACKAGE_SIZE: 52428800 + PLUGIN_PPROF_ENABLED: "false" + +services: + api: + image: *dify_image + container_name: dify-api + restart: unless-stopped + environment: + <<: *common_env + ROLE: api + MODE: api + ports: + - "5001:5001" + volumes: + - dify_storage:/app/storage + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + weaviate: + condition: service_started + plugin_daemon: + condition: service_started + networks: + - dify + + worker: + image: *dify_image + container_name: dify-worker + restart: unless-stopped + environment: + <<: *common_env + ROLE: worker + MODE: worker + volumes: + - dify_storage:/app/storage + depends_on: + - api + - redis + - postgres + networks: + - dify + + beat: + image: *dify_image + container_name: dify-beat + restart: unless-stopped + environment: + <<: *common_env + ROLE: beat + MODE: beat + volumes: + - dify_storage:/app/storage + depends_on: + - api + - redis + - postgres + networks: + - dify + + web: + image: *dify_image + container_name: dify-web + restart: unless-stopped + environment: + <<: *common_env + ROLE: web + PORT: 3000 + NEXT_PUBLIC_API_PREFIX: http://localhost:5001/console/api + NEXT_PUBLIC_PUBLIC_API_PREFIX: http://localhost:5001/api + ports: + - "3000:3000" + depends_on: + - api + networks: + - dify + + plugin_daemon: + image: *dify_image + container_name: dify-plugin-daemon + restart: unless-stopped + environment: + <<: *common_env + ROLE: plugin_daemon + SERVER_PORT: 5002 + PLUGIN_WORKING_PATH: /app/storage/cwd + PLUGIN_STORAGE_LOCAL_ROOT: /app/storage + DIFY_INNER_API_URL: http://api:5001 + DIFY_INNER_API_KEY: "change-this-plugin-key" + ports: + - "5002:5002" + - "5003:5003" + volumes: + - dify_storage:/app/storage + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + networks: + - dify + + postgres: + image: postgres:15-alpine + container_name: dify-postgres + restart: unless-stopped + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: dify_postgres_password + POSTGRES_DB: dify + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d dify"] + interval: 5s + timeout: 5s + retries: 30 + networks: + - dify + + redis: + image: redis:6-alpine + container_name: dify-redis + restart: unless-stopped + command: redis-server --requirepass dify_redis_password + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "-a", "dify_redis_password", "ping"] + interval: 5s + timeout: 5s + retries: 30 + networks: + - dify + + weaviate: + image: semitechnologies/weaviate:1.19.0 + container_name: dify-weaviate + restart: unless-stopped + environment: + QUERY_DEFAULTS_LIMIT: 25 + AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true" + PERSISTENCE_DATA_PATH: /var/lib/weaviate + DEFAULT_VECTORIZER_MODULE: none + CLUSTER_HOSTNAME: node1 + volumes: + - weaviate_data:/var/lib/weaviate + networks: + - dify + +networks: + dify: + driver: bridge + +volumes: + dify_storage: + postgres_data: + redis_data: + weaviate_data: \ No newline at end of file diff --git a/frameworks/Dify/1.14.2/dify-entrypoint.sh b/frameworks/Dify/1.14.2/dify-entrypoint.sh new file mode 100644 index 0000000000000000000000000000000000000000..da7794899a2eea34907606ade5034b01d6ca2441 --- /dev/null +++ b/frameworks/Dify/1.14.2/dify-entrypoint.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROLE="${ROLE:-${MODE:-api}}" + +case "$ROLE" in + api|worker|beat) + export MODE="$ROLE" + cd /app/api + exec /bin/bash /app/api-entrypoint.sh + ;; + + web) + cd /app/web-root + export PORT="${PORT:-3000}" + + if [ -x ./entrypoint.sh ]; then + exec ./entrypoint.sh + fi + + if [ -f ./server.js ]; then + exec node ./server.js + fi + + if [ -f ./targets/next/server.js ]; then + exec node ./targets/next/server.js + fi + + if [ -f ./package.json ]; then + exec npm run start + fi + + echo "Cannot find web startup file" + ls -lah /app/web-root + exit 1 + ;; + + plugin_daemon|plugin-daemon|plugin) + cd /app/plugin-daemon-root + + export SERVER_PORT="${SERVER_PORT:-5002}" + export PLUGIN_WORKING_PATH="${PLUGIN_WORKING_PATH:-/app/storage/cwd}" + export PLUGIN_STORAGE_LOCAL_ROOT="${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}" + + mkdir -p "${PLUGIN_WORKING_PATH}" "${PLUGIN_STORAGE_LOCAL_ROOT}" + + if [ -x ./entrypoint.sh ]; then + exec ./entrypoint.sh + fi + + if [ -x ./dify-plugin-daemon ]; then + exec ./dify-plugin-daemon + fi + + if [ -x ./plugin_daemon ]; then + exec ./plugin_daemon + fi + + if [ -x ./main ]; then + exec ./main + fi + + echo "Cannot find plugin daemon executable" + ls -lah /app/plugin-daemon-root + exit 1 + ;; + + *) + echo "Unknown ROLE/MODE: $ROLE" + echo "Allowed: api, worker, beat, web, plugin_daemon" + exit 1 + ;; +esac diff --git a/frameworks/Dify/1.14.2/test.sh b/frameworks/Dify/1.14.2/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..9f0a51ecf5d185e6e897563c68f1a4efc27e7837 --- /dev/null +++ b/frameworks/Dify/1.14.2/test.sh @@ -0,0 +1,195 @@ +#!/bin/bash +set -e + +IMAGE="${1:?ERROR: 缺少镜像参数。用法: bash test.sh }" +DOCKER="${DOCKER:-docker}" + +echo "=== Dify OpenCloudOS 单镜像基础功能测试 ===" +echo "IMAGE: $IMAGE" +echo + +run_test() { + local name="$1" + shift + + echo -n "检查 ${name}... " + if $DOCKER run --rm "$@" "$IMAGE" >/tmp/dify-test.log 2>&1; then + echo "✓ 通过" + else + echo "✗ 失败" + echo "---- 日志 ----" + cat /tmp/dify-test.log + echo "------------" + exit 1 + fi +} + +# 1. 镜像基础命令 +run_test "容器基础启动" \ + --entrypoint bash \ + -e ROLE=api \ + "$IMAGE" \ + -lc "echo container-ok" + +# 2. python3 / Dify API 虚拟环境 +run_test "python3 运行环境" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + python3 --version + /app/api/.venv/bin/python3 --version + test -x /app/api/.venv/bin/python3 + " + +# 3. Dify 后端基础 import +run_test "Dify API import" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + cd /app/api + /app/api/.venv/bin/python3 - <<'PY' +import os +import sys + +print('python3:', sys.version) +import flask +import celery +import sqlalchemy +import redis + +print('flask:', flask.__version__ if hasattr(flask, '__version__') else 'ok') +print('celery:', celery.__version__) +print('sqlalchemy:', sqlalchemy.__version__) +print('redis:', redis.__version__) +print('dify api imports ok') +PY + " + +# 4. API 入口文件检查 +run_test "API 启动入口" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + test -f /app/api-entrypoint.sh + test -x /app/api-entrypoint.sh + test -d /app/api + test -f /app/api/app.py || test -f /app/api/app_factory.py || find /app/api -maxdepth 2 -name 'app.py' | grep -q . + " + +# 5. Worker / Beat 依赖检查 +run_test "Worker / Beat 基础依赖" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + cd /app/api + /app/api/.venv/bin/celery --version + /app/api/.venv/bin/python3 - <<'PY' +import celery +from celery import Celery + +app = Celery('dify-test') +assert app.main == 'dify-test' +print('celery basic ok') +PY + " + +# 6. Node.js / Web 基础检查 +run_test "Node.js / Web 运行环境" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + node --version + npm --version + test -d /app/web-root + cd /app/web-root + test -f package.json || test -f server.js || test -d targets + echo 'web files ok' + " + +# 7. Web 启动文件检查 +run_test "Web 启动文件" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + cd /app/web-root + + if [ -d ./web ]; then + cd ./web + fi + + if [ -x ./entrypoint.sh ]; then + echo 'found web entrypoint.sh' + elif [ -f ./server.js ]; then + echo 'found server.js' + elif [ -f ./targets/next/server.js ]; then + echo 'found targets/next/server.js' + elif [ -f ./package.json ]; then + echo 'found package.json' + else + echo 'no web startup file found' + pwd + ls -lah + exit 1 + fi + " + +# 8. Plugin Daemon 文件检查 +run_test "Plugin Daemon 文件" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + test -d /app/plugin-daemon-root + cd /app/plugin-daemon-root + + if [ -x ./entrypoint.sh ]; then + echo 'found plugin entrypoint.sh' + elif [ -x ./dify-plugin-daemon ]; then + echo 'found dify-plugin-daemon' + elif [ -x ./plugin_daemon ]; then + echo 'found plugin_daemon' + elif [ -x ./main ]; then + echo 'found main' + else + echo 'no plugin daemon executable found' + ls -lah + exit 1 + fi + " + +# 9. ROLE 参数分发逻辑检查 +run_test "ROLE 非法参数校验" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + set +e + ROLE=invalid-role /usr/local/bin/dify-entrypoint >/tmp/role-test.log 2>&1 + code=\$? + cat /tmp/role-test.log + test \$code -ne 0 + grep -q 'Unknown ROLE' /tmp/role-test.log + " + +# 10. CUDA 基础检查 +run_test "CUDA 编译环境" \ + --entrypoint bash \ + "$IMAGE" \ + -lc " + if command -v nvcc >/dev/null 2>&1; then + nvcc --version + else + echo 'nvcc not found' + exit 1 + fi + " + +# 11. GPU 运行时检查:有 GPU 环境则检查 nvidia-smi,没有则跳过 +echo -n "检查 GPU Runtime / nvidia-smi... " +if $DOCKER run --rm --gpus all --entrypoint bash "$IMAGE" -lc "nvidia-smi" >/tmp/dify-test.log 2>&1; then + echo "✓ 通过" +else + echo "⚠ 跳过或不可用" + echo "说明:当前 CI/宿主机可能未配置 NVIDIA Container Runtime,或没有 GPU。" +fi + +echo +echo "=== 所有基础测试通过 ===" \ No newline at end of file diff --git a/frameworks/Dify/1.14.2/test_result.png b/frameworks/Dify/1.14.2/test_result.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e7ff4fa74cfd716b9ff3c1a6b1aff1ff53b22a Binary files /dev/null and b/frameworks/Dify/1.14.2/test_result.png differ