1. 问题现象
在自部署 draw.io(项目地址)中关联 Google Drive 时,Google OAuth 返回错误:
|
|
部署环境:
|
|
2. Google OAuth 应有配置
draw.io 外部访问地址:
|
|
Google Cloud Console 中 OAuth Client 类型应为:
|
|
对应配置:
|
|
|
|
draw.io 容器环境变量:
|
|
说明:
|
|
例如:
|
|
3. 最初怀疑方向
最初看到 Google 报错:
|
|
因此首先检查以下内容:
- Google Cloud Console 中是否配置了精确的 redirect URI;
- OAuth Client ID 是否和 draw.io 环境变量中的 Client ID 一致;
- Traefik 是否正确反代到 draw.io 容器;
- draw.io 是否配置了正确的外部访问地址;
- 容器是否重启 / 重建使环境变量生效。
以上都检查后,错误仍然存在。
4. 关键发现一:线上 PreConfig.js 仍是默认内容
访问:
|
|
发现返回的仍是 draw.io 默认配置:
|
|
而正常情况下,启用 DRAWIO_SERVER_URL 和 Google OAuth 后,应该出现类似:
|
|
这说明:
|
|
5. 关键发现二:容器内 Google client 文件仍是占位值
进入容器检查:
|
|
结果只有默认内容:
|
|
检查 Google client 文件:
|
|
结果是:
|
|
这进一步证明:
|
|
因此,Google OAuth 实际使用的不是预期 Client ID,而是镜像内的默认占位/旧配置,最终导致 redirect_uri_mismatch。
6. 检查容器环境变量
执行:
|
|
输出显示环境变量确实存在:
|
|
因此排除:
|
|
问题转为:
|
|
7. 检查 entrypoint 和日志
检查容器实际 entrypoint:
|
|
结果:
|
|
说明 entrypoint 确实执行。
继续检查日志:
|
|
发现大量权限错误:
|
|
这说明:
|
|
8. 检查容器用户和文件权限
容器内执行:
|
|
结果:
|
|
检查文件权限:
|
|
结果:
|
|
权限含义:
|
|
也就是:
|
|
当前进程用户是:
|
|
虽然属于 tomcat 组,但 group 没有写权限,因此无法写入文件。
9. 查询镜像内 tomcat 用户
执行:
|
|
结果:
|
|
说明:
|
|
而 draw.io 的文件 owner 正是:
|
|
因此正确运行用户应为:
|
|
10. 关键发现三:TrueNAS rendered compose 中 user 配置错误
通过 inspect 找到 TrueNAS 生成的 compose 文件路径:
|
|
关键字段:
|
|
查看 compose 文件:
|
|
发现虽然环境变量里有:
|
|
但真正的 Docker 运行用户是:
|
|
关键点:
|
|
因此容器实际仍然以:
|
|
运行,导致权限不足。
11. 最终根因
最终根因:
|
|
修复步骤
问题原因调查清楚了,如何修复该问题呢?
既然我们已经知道了根本原因,修复起来 也不是特别复杂:
- 只要修改 TrueNAS 应用对应的配置文件
/mnt/.ix-apps/app_configs/drawio/versions/1.4.27/templates/rendered/docker-compose.yaml中的"user": "1000:999"–>"user": "1001:999" - 然后重建 这个docker 应用就可以了,既有的配置不用改。
详细操作步骤如下——
TODO 1:确认 Google OAuth 配置
在 Google Cloud Console 中确认 OAuth Client 类型为:
|
|
确认配置:
|
|
|
|
确认 Client ID:
|
|
TODO 2:确认 draw.io 容器环境变量
容器环境变量应包含:
|
|
检查命令:
|
|
TODO 3:找到 TrueNAS 生成的 compose 文件路径
执行:
|
|
关注字段:
|
|
本次路径为:
|
|
项目名:
|
|
服务名:
|
|
TODO 4:备份 rendered compose 文件
|
|
TODO 5:修改 compose 中真正的运行用户
由于文件内容实际是 JSON,可以使用 Python 修改。
将:
|
|
改为:
|
|
执行:
|
|
确认:
|
|
预期:
|
|
TODO 6:用 TrueNAS rendered compose 强制重建 drawio 服务
执行:
|
|
说明:
不要在 /root 下直接执行:
|
|
否则会报:
|
|
因为 TrueNAS 的 compose 文件不在当前目录,而在 rendered 配置路径下。
TODO 7:验证新容器运行用户
查新容器:
|
|
检查用户:
|
|
预期:
|
|
如果仍然是:
|
|
说明 compose 修改没有生效,或者被 TrueNAS 重新渲染覆盖。
TODO 8:验证 entrypoint 已成功写入配置
检查日志:
|
|
预期:
|
|
并且不应再出现:
|
|
TODO 9:验证 PreConfig.js
执行:
|
|
预期输出:
|
|
TODO 10:验证服务端 Google Client ID 文件
执行:
|
|
预期:
|
|
不要打印 secret 内容,只检查长度:
|
|
TODO 11:浏览器侧重新测试
建议使用无痕窗口访问:
|
|
或者强制刷新:
|
|
然后重新执行 Google Drive 关联。
如果仍然报错,检查 Google 错误页中的:
|
|
应为:
|
|
TODO 12:安全处理 Client Secret
由于 OAuth Client Secret 曾经在聊天或日志中出现过,建议修复完成后重新生成。
Google Cloud Console:
|
|
然后更新 TrueNAS / compose 中:
|
|
再重建 drawio 服务。
后续维护注意事项
1. TrueNAS rendered compose 可能被覆盖
本次修改的是:
|
|
这是 TrueNAS 渲染后的 compose 文件。
后续如果发生以下操作,可能会被覆盖:
|
|
如果 draw.io Google Drive 功能以后再次失效,优先检查:
|
|
确认是否仍为:
|
|
如果被恢复为:
|
|
需要重新改回:
|
|
并重建服务。
2. 最佳长期方案
更长期、更稳定的方案是使用自定义 App / 自维护 compose,明确写入:
|
|
这样避免 TrueNAS App 模板重新渲染时把 user 改回错误值。
最终结论
本次问题表面是 Google OAuth:
|
|
但实际根因不是 Google Cloud Console 配错,也不是 Traefik 反代问题,而是:
|
|
修复方式:
|
|
修复后使用正确的环境变量值:
|
|
就可以成功写入tomcat 配置文件:
|
|
最后验证下:
这回drawio 应用与Google Drive 的关联就正常了。
参考文章:
-
项目代码:https://github.com/jgraph/docker-drawio
-
项目启动程序:https://github.com/jgraph/docker-drawio/blob/dev/main/docker-entrypoint.sh
1 2 3 4 5 6 7 8if ! touch $CATALINA_HOME/webapps/draw/js/PreConfig.js 2>/dev/null; then echo "WARNING: No write access to $CATALINA_HOME (running as UID $(id -u), GID $(id -g))." echo " Skipping runtime configuration: DRAWIO_* environment variables, SSL and the" echo " context path will NOT be applied. To run as an arbitrary user, give it GID 0," echo " e.g. 'docker run --user 1234:0', compose 'group_add: [\"0\"]' or kubernetes" echo " 'runAsGroup: 0' / 'supplementalGroups: [0]'. See README: Running as non-root." exec "$@" fi