Skip to content

[oneclick.sh] Docker 部署迁移至 oneclick.sh 原生部署时的兼容性问题汇总 #89

@seasidedog24

Description

@seasidedog24

背景

我先使用 Docker 方式(deploy_all.sh)部署了 WebRTC Demo,之后尝试按照 oneclick.md 切换到 oneclick.sh 原生部署(macOS Apple Silicon, 24GB Mac mini M4)。在迁移过程中遇到了一系列问题,汇总如下。

环境信息:

  • macOS 15 (Darwin 25.2.0), Apple M4, 24GB RAM
  • Python 3.14, Node.js v24, Bash 3.2 (macOS 默认)
  • 已有 Docker 预构建包 WebRTC_Demo/ 和本地 GGUF 模型

问题 1:pyproject.toml 版本号不符合 PEP 440 规范

文件: omini_backend_code/code/pyproject.toml

现象: pip install -e . 安装后端依赖时报错:

ValueError: invalid pyproject.toml config: 'project.version'.
configuration error: 'project.version' must be pep440

原因: Docker 预构建包中版本号为 "0.1.0-lite",不符合 PEP 440 规范(连字符不允许作为 pre/post release 分隔符)。

建议修复:

# Before
version = "0.1.0-lite"

# After (任选一种 PEP 440 合法格式)
version = "0.1.0"
version = "0.1.0.post1"
version = "0.1.0+lite"      # local version label

问题 2:local.yaml 包含 Docker 专用配置,注释有误导性

文件: omini_backend_code/code/config/local.yaml

现象: 后端连接 LiveKit 时报错:

failed to lookup address information: nodename nor servname provided, or not known

随后刷新页面显示 "Server at capacity"。

原因: local.yaml 中 LiveKit URL 写的是 Docker Compose 内部主机名:

livekit:
  url: "ws://livekit:7880"  # Docker Compose 服务名
  api_key: "devkey"
  api_secret: "secret"       # 仅 6 字符,LiveKit v1.9+ 要求 >= 32 字符

oneclick.sh 通过环境变量(LIVEKIT_URL=ws://localhost:7880)正确覆盖了这个配置,所以使用 oneclick.sh 正常启动时不会触发此问题。但如果用户按照注释理解 local.yaml 就是"本地部署配置"并尝试手动启动后端(不带环境变量),就会失败。

建议修复:

  1. local.yaml 重命名为 docker.yaml(对应 APP_ENV=docker),明确其 Docker 专用性
  2. 或新增一个 native.yaml 文件包含正确的本地配置(ws://localhost:7880 + 32 字符 secret)
  3. 至少修改注释,明确标注"此配置仅适用于 Docker Compose 环境,原生部署请使用 oneclick.sh 或手动设置环境变量"

问题 3:前端 node_modules 平台不兼容(Docker → macOS ARM64)

文件: o45-frontend/node_modules/

现象: 前端构建时报错:

Error: Cannot find module @rollup/rollup-darwin-arm64
... library load disallowed by system policy

原因: Docker 预构建包中的 node_modules 是为 Linux x86_64 编译的原生模块。oneclick.shstart_frontend() 只检查 node_modules 目录是否存在(oneclick.sh L1127),不验证平台兼容性:

if [[ ! -d "$FRONTEND_DIR/node_modules" ]]; then
    # 只有目录不存在时才重新安装

建议修复(任选):

  • 方案 A: 添加平台指纹校验(推荐)
# 记录安装时的平台
PLATFORM_MARKER="$FRONTEND_DIR/node_modules/.platform"
CURRENT_PLATFORM="$(uname -s)-$(uname -m)"
if [[ ! -d "$FRONTEND_DIR/node_modules" ]] || \
   [[ "$(cat "$PLATFORM_MARKER" 2>/dev/null)" != "$CURRENT_PLATFORM" ]]; then
    rm -rf "$FRONTEND_DIR/node_modules"
    pnpm install
    echo "$CURRENT_PLATFORM" > "$PLATFORM_MARKER"
fi
  • 方案 B: 在文档中提示迁移时需删除 node_modules
# 迁移前清理
rm -rf WebRTC_Demo/o45-frontend/node_modules

问题 4:serve-prod.mjs 缺失(Docker 预构建包不完整)

文件: o45-frontend/serve-prod.mjs

现象: FRONTEND_MODE=prod(oneclick.sh 默认)启动前端时报错:

Error: Cannot find module '/path/to/o45-frontend/serve-prod.mjs'

原因: Docker 预构建包是打包好的部署文件,不包含 serve-prod.mjs(该文件用于生产模式静态服务器)。oneclick.sh 假设 WebRTC_Demo/ 是从 git 完整克隆的,但 Docker 预构建包缺少此文件。

建议修复(任选):

  • 方案 A: oneclick.shstart_frontend() 中检查 serve-prod.mjs 是否存在,缺失时自动从 git 补全
  • 方案 B:serve-prod.mjs 也加入 Docker 预构建包
  • 方案 C:preflight_check() 中添加完整性校验,检测到 Docker 预构建包时提示用户需要重新下载

问题 5:macOS Bash 3.2 不兼容 ${name,,} 语法

文件: oneclick.sh 第 319 行

现象: macOS 下运行报错:

oneclick.sh: line 319: bad substitution

原因: ${name,,}(转小写)是 Bash 4.0+ 语法,macOS 默认 Bash 为 3.2(Apple 因 GPLv3 许可停止更新)。

# 第 319 行
err "Check logs: tail -50 $LOG_DIR/${name,,}.log"

建议修复:

# 兼容 Bash 3.2 的写法
local name_lower
name_lower=$(echo "$name" | tr '[:upper:]' '[:lower:]')
err "Check logs: tail -50 $LOG_DIR/${name_lower}.log"

注意:脚本第 1 行声明了 #!/usr/bin/env bash,且用了 set -euo pipefail,这都兼容 Bash 3.2。但 ${name,,} 不兼容。建议全局搜索其他 Bash 4+ 语法。


问题 6(轻微):C++ 推理服务默认注册端口与后端实际端口不一致

文件: cpp_server/minicpmo_cpp_http_server.py

现象: 手动启动 C++ 推理服务时,它尝试向 port 8025 注册,而后端实际运行在 port 8021

ConnectionError: HTTPConnectionPool(host='192.168.9.247', port=8025):
Failed to establish a new connection: Connection refused

原因: minicpmo_cpp_http_server.py 内硬编码的默认注册端口为 8025,与 oneclick.sh 中后端默认端口 8021 不一致。oneclick.sh 通过 REGISTER_URL 环境变量传了正确值,所以正常流程不受影响,但手动启动会遇到此问题。

建议修复: 将默认注册端口改为 8021,或添加 --register-url 命令行参数。


复现步骤(完整迁移路径)

# 1. 先用 Docker 方式部署(用户初次尝试)
cd ~/Downloads/WebRTC_Demo
bash deploy_all.sh

# 2. 发现性能问题(Docker + Rosetta2 模拟层 + 内存开销),决定切换原生部署
docker compose down

# 3. 下载 oneclick.sh 放在 WebRTC_Demo 同级目录
# oneclick.sh 检测到已有 WebRTC_Demo/ 目录,复用它 → 触发上述所有问题
PYTHON_CMD=/path/to/python bash oneclick.sh start

建议

最核心的改进点是让 oneclick.sh 能够检测并处理 Docker 预构建包的场景,而不是假设 WebRTC_Demo/ 一定是从 git 完整克隆的。可以通过以下方式之一实现:

  1. preflight_check() 中检查 .git 目录或特征文件,区分 Docker 包和 git 克隆
  2. 对关键文件(serve-prod.mjsnode_modules 平台兼容性、pyproject.toml 版本号)逐一做完整性校验
  3. 在文档中明确提示"从 Docker 迁移时需先删除 WebRTC_Demo/ 目录,让 oneclick.sh 重新下载"

感谢开发团队的工作!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions