1. 故障现象
今早发现私有化部署在 Docker 中的 Matomo 统计系统无法访问。浏览器报错: ERR_TOO_MANY_REDIRECTS (重定向次数过多)。
环境背景:
- 架构: CDN (如 Cloudflare) -> Nginx 反向代理 -> Docker (Matomo 官方镜像)
- 状态: 此前已稳定运行较长时间,未手动修改配置,今早突发故障。
2. 原因深度分析
经过排查,本次故障是由 “容器版本自动更新” 与 “内部强制 SSL 配置” 共同触发的。
核心诱因:版本跨越
Matomo 容器镜像(latest 标签)在自动重启或拉取后触发了更新。由于代码版本超前于现有数据库版本,Matomo 内部触发了自我保护机制:强制重定向所有请求至 CoreUpdater(核心更新程序)页面。
致命死循环:SSL 握手冲突
在原有的 config.ini.php 中,开启了 force_ssl = 1。
- Matomo 容器:检测到需要升级数据库,发出
302重定向指令跳转至升级页面。 - 强制跳转逻辑:由于
force_ssl开启,Matomo 强行将跳转目标设为https://。 - 反向代理冲突:由于请求经过了反向代理,Matomo 内部未能正确识别当前的 HTTPS 状态,认为用户仍在通过 HTTP 访问,于是再次发出“跳转到 HTTPS”的指令,导致浏览器陷入无限循环。
3. 故障处理过程(脱敏实操)
第一步:打破重定向循环
首先需要进入容器修改配置文件,让 Matomo 信任反向代理提供的 SSL 环境。
- 修改配置文件: 编辑
config/config.ini.php,在[General]段落进行如下调整:force_ssl = 0(将强制跳转交给外层 Nginx/CDN 处理)。assume_ssl = 1(强制让 Matomo 认同当前的加密环境)。proxy_client_headers[] = "HTTP_X_FORWARDED_FOR"(启用代理头识别)。
- 清理缓存: 在容器内执行以下命令,确保新配置立即生效:Bash
php console cache:clear
第二步:命令行完成数据库升级
循环打破后,页面会提示数据库需要升级。为了防止网页端因大数据量升级导致超时,推荐直接在服务端命令行操作:
Bash
docker exec -u www-data <matomo_container_id> php console core:update --yes
第三步:验证恢复
升级完成后,通过 curl 在服务器本地测试:
Bash
curl -I http://127.0.0.1:<mapping_port>
当看到 Location 变为相对路径(如 index.php?module=CoreHome...)且不再循环跳转时,说明修复成功。
4. 经验总结与预防措施
- 解耦 SSL 逻辑:在存在反向代理的架构中,应用容器内部的
force_ssl应保持关闭,统一由最前端(如 Nginx 或 Cloudflare)实现 HTTPS 强制跳转。 - 反向代理标配:私有化部署 Matomo 时,务必在
config.ini.php中固定assume_ssl = 1等代理相关参数,防止因环境波动触发跳转 Bug。 - 版本锁定建议:生产环境的 Docker 镜像建议锁定具体版本号(如
matomo:5.6),避免:latest标签在无人值守时自动更新导致业务中断。
博主结语: ERR_TOO_MANY_REDIRECTS 是私有化部署中的“老常客”,核心思路永远是:理清谁在握手,谁在转发,谁在强行跳转。