bug: entrypoint.sh prints misleading “CLICKHOUSE_PASSWORD … not URL-encoded” hint on every ClickHouse migration failure

该报错通常出现在自托管 Langfuse(docker-compose)时 ClickHouse 迁移失败的任何场景。优先排查 schema_migrations 表的 dirty 状态和数据库连通性,不要被误导性的密码提示带偏;如果密码确实是纯字母数字,基本可以排除密码问题。

快速结论:该报错通常出现在自托管 Langfuse(docker-compose)时 ClickHouse 迁移失败的任何场景。优先排查 schema_migrations 表的 dirty 状态和数据库连通性,不要被误导性的密码提示带偏;如果密码确实是纯字母数字,基本可以排除密码问题。

适用环境:自托管 Langfuse,官方 docker-compose.yml,镜像 docker.langfuse.com/langfuse/langfuse:4。涉及文件为 web/entrypoint.sh:108-125(ClickHouse 迁移块)和 packages/shared/clickhouse/scripts/up.sh

最快修复方案:暂无确认的“一键修复”方案,但可优先尝试清理 ClickHouse 中脏迁移状态:连接 ClickHouse 执行 SELECT * FROM default.schema_migrations;,确认 dirty 状态后,将 dirty 字段重置为 0(或删除部分应用的迁移记录),再重启 web 容器。

注意事项:上述修复操作需要手动审查迁移是否部分应用,直接重置 dirty 字段可能掩盖未完成的迁移语句,建议先确认迁移脚本 up.sh 中对应版本的 SQL 是否已完整执行。

问题场景

用户通过官方 docker-compose.yml 自托管 Langfuse,设置纯字母数字密码(如 CLICKHOUSE_PASSWORD=password,无特殊字符)。在 ClickHouse 迁移执行期间中断 Docker 进程(如 Ctrl+C 或容器被 kill),再次启动时 web 容器崩溃,日志中同时出现 “Common cause 2: CLICKHOUSE_PASSWORD … not URL-encoded” 和真实的 Dirty database version 报错。

报错原文

Applying clickhouse migrations failed. Common causes:
  1. The database is unavailable or unreachable.
  2. CLICKHOUSE_PASSWORD contains special characters that are not URL-encoded.

error: Dirty database version 1. Fix and force version.

原因分析

可能原因:web/entrypoint.sh 中第 121 行附近,将 “CLICKHOUSE_PASSWORD 包含未 URL 编码的特殊字符” 列为每次 ClickHouse 迁移失败的通用原因(无条件打印),而实际检测密码内容的 check_clickhouse_password() 函数是有条件触发的。当密码本身是纯字母数字时,这条提示具有误导性。

本 Issue 的真实故障是:上一次 docker compose up 被中断(容器退出码 137),ClickHouse 迁移 1 正在应用时中断,导致 schema_migrations 表停留在 version=1, dirty=1 状态。ClickHouse 认证全程正常,密码并非问题根因。

环境排查

  • 确认 Docker 镜像版本:是否为 docker.langfuse.com/langfuse/langfuse:4(较新版本已移除无条件密码提示,但 langfuse:4 镜像可能仍包含该逻辑)。
  • 确认 CLICKHOUSE_PASSWORD 是否确实只包含字母数字(不含 & = # ? % + @ space 等 URL 不安全字符)。
  • 检查 ClickHouse 容器是否可达:docker compose ps 确认 clickhouse 服务状态。
  • 检查 schema_migrations 表当前状态:SELECT * FROM default.schema_migrations;,关注 versiondirty 字段。

解决步骤

  1. 先确认密码不是问题:查看 CLICKHOUSE_PASSWORD 是否包含 URL 特殊字符;如果为纯字母数字,直接跳过密码排查。
  2. 连接 ClickHouse 实例(docker compose exec clickhouse clickhouse-client 或通过 ClickHouse Cloud 控制台),执行 SELECT * FROM default.schema_migrations;,查看 versiondirty 字段。
  3. 判断 dirty 迁移版本的 SQL 是否已部分应用:比较 up.sh 中该版本的 SQL 内容与数据库实际表结构/数据。如果迁移语句只执行了一半,先手动补齐剩余语句;如果完全未执行或不需要执行,可将 dirty 重置为 0
  4. 重置脏迁移状态(示例,按实际表名调整):UPDATE default.schema_migrations SET dirty = 0 WHERE version = 1; (需确认 ClickHouse 的 mutation 语句语法;也可删除该行记录让迁移重新执行)。
  5. 重启 web 容器:docker compose restart web(或 docker compose up -d),观察日志确认迁移从干净状态重新运行。
  6. 如果希望避免后续再次被误导,可关注 Langfuse 上游修复:较新版本已移除无条件密码提示(参考 PR #13186 的设计思路——密码提示仅在密码实际包含 URL 不安全字符时显示)。

验证方法

重启 web 容器后,观察日志是否不再出现 Dirty database version 报错,ClickHouse 迁移正常完成,Langfuse 前端可正常访问。同时确认日志中不再出现误导性的 “Common cause 2” 提示(或确认更新到修复版本后该提示已被移除)。

参考来源

langfuse/langfuse #16440

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 20172

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注