Umami 3.4 配置参数详解

系统梳理 Umami 3.4.0 全部配置参数:数据库连接、端口、APP_SECRET、采集开关与隐私模式等,含参数总览表与生产配置模板,运行时行为类参数均实测验证并照录回显。

UmamiUmami2026/10/17

Umami 3.4 配置参数详解

目标:系统梳理 Umami 3.4.0 的全部配置参数——每个参数的含义、引入版本、默认值、修改方式与实测验证手段;运行时行为类参数(APP_SECRET/TRACKER_SCRIPT_NAME/COLLECT_API_ENDPOINT/CLIENT_IP_HEADER/PORT/DISABLE_TELEMETRY/PRIVATE_MODE 等)均在 Ubuntu 22.04 LTS(x86_64)+ Umami 3.4.0 + PostgreSQL 16.15 环境逐项实测,实测回显逐条照录。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • Umami:3.4.0(镜像 ghcr.io/umami-software/umami:postgresql-latest,服务内版本号实测 3.4.0)
  • 数据库:PostgreSQL 16.15;Redis:未启用(可选组件)
  • 服务监听:0.0.0.0:3000(实测实例对外端口 13000,另起 13001~13007 端口做参数对照组)
  • 参考底稿:官方文档 Environment Variables 页(docs.umami.is,2026-10-17 抓取),逐项标注官方引入版本
  • 管理账号:admin / q1w2e3r4(演示口令)

二、前置条件

  • Umami 3.4.0 已部署并可访问(心跳 {"ok":true}),部署过程见《Umami Docker Compose 部署指南》;
  • 修改参数的方式:在编排文件 environment: 段增删变量后 docker compose up -d 重建服务生效(环境变量驱动,无配置文件;直接 docker run 的用户等价改 -e 参数重建服务);
  • 本文多个验证项需要"同库双实例"对照:两实例连同一数据库、不同 APP_SECRET/端口,用于验证令牌隔离等行为。命令模式如下(实测用例):
docker run -d --name umami-envtest-a --network umami_default -p 13001:3000 \
  -e DATABASE_URL='postgresql://umami:q1w2e3r4@umami-db:5432/umami' \
  -e DATABASE_TYPE=postgresql \
  -e APP_SECRET='EnvTestSecretA-0123456789abcdef' \
  ghcr.io/umami-software/umami:postgresql-latest

实测回显(启动后心跳):

{"ok":true}

三、参数查看与修改方式

Umami 没有主配置文件,全部参数通过环境变量注入,分三类:

  1. 运行时变量:服务启动时读取,改后重启服务即生效(如 APP_SECRET、PORT、DISABLE_TELEMETRY);
  2. 构建时变量:只在构建镜像时生效(如 BASE_PATH、ALLOWED_FRAME_URLS、DATABASE_TYPE),官方文档明确标注"Build time variables are only recognized during the build process";用官方 Docker 镜像时此类变量多数已固化,需要自定义构建才能改;
  3. 数据库内配置:用户偏好(语言/时区)、网站设置、团队与角色等存库,在控制台或 API 修改,不属于环境变量。

修改与生效流程(Compose 部署):

cd /opt/umami-doc-lab
vi compose.yml          # 在 umami 服务的 environment: 段增删变量
docker compose up -d    # 重建服务生效
docker compose logs --tail 5 umami

实测回显(重建后正常拉起):

umami-app  | ✓ Database is up to date.
umami-app  | ▲ Next.js 16.3.4
umami-app  | - Local:         http://localhost:3000
umami-app  | ✓ Ready in 0ms

验证参数是否生效的通用手段(下文逐参数演示):

  • 端口/监听类:心跳与 curl -I 直连新端口;
  • 鉴权类:跨实例用旧令牌请求 401 与否;
  • 采集类:请求新脚本/新端点路径看 200/404;
  • 隐私类:/telemetry.js 回显内容(正常返回像素注入 JS,关闭时返回 /* telemetry disabled */)。

四、参数总览

运行时变量(官方文档口径 + 本文实测项打 ✅):

变量版本默认值作用实测
DATABASE_URLv1.0.0无(唯一必填)数据库连接串✅
DATABASE_TYPEv2.0.0无数据库类型,Docker 构建期必填✅
APP_SECRETv1.0.0无(强烈建议设置)令牌签名密钥,每实例唯一✅
PORT / HOSTNAMEv1.0.03000 / -监听端口/主机名✅(PORT)
CLIENT_IP_HEADERv1.24.0无(自动取连接 IP)指定存放客户端 IP 的头✅
COLLECT_API_ENDPOINTv1.34.0/api/send采集端点改名(防拦截)✅
TRACKER_SCRIPT_NAMEv1.26.0script.js统计脚本改名(防拦截)✅
DISABLE_TELEMETRYv2.0.0未设(开启遥测)关闭匿名遥测✅
PRIVATE_MODEv2.11.0未设切断全部外网请求✅
SALT_ROTATIONv3.1.0month会话盐值轮换周期官方口径
REDIS_URLv3.0.1未设(关闭)缓存/协调用 Redis官方口径
GEO_DATABASE_URLv2.0.0未设MaxMind 兼容 MMDB 下载地址官方口径
IGNORE_IPv1.0.0未设排除的 IP/CIDR 列表官方口径
IGNORE_HOSTNAMEv1.0.0未设排除的主机名官方口径
IGNORE_PATHSv1.0.0未设排除的路径(通配)官方口径
REMOVE_TRAILING_SLASHv1.26.0未设去除 URL 尾斜杠官方口径
DISABLE_BOT_CHECKv2.0.0未设(排除机器人)关闭机器人识别官方口径
DISABLE_LOGINv1.26.0未设关闭登录页官方口径
DISABLE_UPDATESv1.33.0未设关闭新版本检查官方口径
DISABLE_UI—未设仅暴露采集接口(自用嵌入式)官方口径
DISABLE_ADMIN—未设关闭管理后台入口官方口径
FORCE_SSLv1.0.0未设全响应加 HSTS 头官方口径
LOG_LEVEL—info日志级别官方口径
LOG_QUERYv2.0.0未设控制台打印 SQL(开发用)官方口径
DEBUGv2.0.0未设指定模块日志(umami:auth 等)官方口径
ENABLE_TEST_CONSOLEv2.0.0未设/console 测试页手动打点官方口径
FAVICON_URLv2.18.0icons.duckduckgo.com站点图标服务地址官方口径
CORS_MAX_AGEv2.0.086400CORS 预检缓存秒数官方口径
SKIP_LOCATION_HEADERSv2.15.0未设忽略 CDN 地理头,强制用本地库官方口径
TWO_FACTOR_ENCRYPTION_KEYv3.3.0未设2FA 密钥(64 位 hex),启用 2FA 前必配官方口径
USE_UUIDV7v3.0.2未设(UUIDv4)标识改用 UUIDv7官方口径
DIRECT_DATABASE_URLv3.2.0未设迁移命令专用连接串(pooled 场景)官方口径
MCP_ENABLEDv3.4.0未设(关闭)启用 /mcp 端点官方口径

构建时变量(改这些需要自行构建镜像):

变量版本作用
ALLOWED_FRAME_URLSv2.3.0允许 iframe 嵌入本应用的外部 URL 列表
BASE_PATHv1.9.0子路径部署前缀(如 /umami),需反代配合
DEFAULT_CURRENCY / DEFAULT_LOCALEv3.1.0用户未选偏好时的默认币种/语言
BUILD_GEO / SKIP_BUILD_GEOv3.0.0 / v3.1.0构建期 GeoIP 库步骤开关
SKIP_DB_CHECK / SKIP_DB_MIGRATIONv2.0.0跳过构建期库检查/迁移

💡 说明:表中"官方口径"表示含义与默认值以官方文档为准、未在本文环境单独复现;打 ✅ 的参数均附实测小节。DISABLE_UI/DISABLE_ADMIN/LOG_LEVEL 为官方仓库示例 compose 与镜像默认值中出现的口径。

关键差异与如何读这张表:先保证唯一必填的 DATABASE_URL,再按需求挑"安全三件套"(APP_SECRET/FORCE_SSL/CLIENT_IP_HEADER)与"防拦截两件套"(TRACKER_SCRIPT_NAME/COLLECT_API_ENDPOINT);隐私敏感环境加 PRIVATE_MODE=1;其余按需。

五、核心参数分类详解

本节按「数据库 → 安全 → 采集与追踪 → 隐私 → 服务器与日志 → 缓存与扩展」六类展开;每项给出:取值/默认值、修改方法、实测验证(命令 + 真实回显)。

5.1 数据库连接:DATABASE_URL / DATABASE_TYPE / DIRECT_DATABASE_URL

DATABASE_URL 是唯一必填参数,指向 PostgreSQL 或 MySQL 连接串;DATABASE_TYPE=postgresql|mysql 声明类型(官方口径:Docker 构建期必填)。启动日志可确认连接与迁移状态(实测):

umami-app  | ✓ DATABASE_URL is defined.
umami-app  | ✓ Database connection successful.
umami-app  | ✓ Database version check successful.
umami-app  | Datasource "db": PostgreSQL database "umami", schema "public" at "umami-db:5432"
umami-app  | 26 migrations found in prisma/migrations

官方另有 DIRECT_DATABASE_URL(v3.2.0,供 Prisma 迁移命令使用的直连串——当 DATABASE_URL 指向 PgBouncer 等 pooled 连接时,迁移须走直连串)。

实测:密码含特殊字符时"未编码"与"URL 编码"两种写法对照(数据库用户 umami2,真实密码 p@ss:w0rd):

# 写法一:密码原样写(未编码)
docker run -d --name umami-envtest-bad --network umami_default -p 13009:3000 \
  -e DATABASE_URL='postgresql://umami2:p@ss:w0rd@umami-db:5432/umami' \
  -e DATABASE_TYPE=postgresql \
  ghcr.io/umami-software/umami:postgresql-latest

实测回显(心跳 200,启动正常):

✓ DATABASE_URL is defined.
✓ Database connection successful.
✓ Ready in 0ms
{"ok":true}
# 写法二:URL 编码(@ → %40,: → %3A)
docker run -d --name umami-envtest-good --network umami_default -p 13010:3000 \
  -e DATABASE_URL='postgresql://umami2:p%40ss%3Aw0rd@umami-db:5432/umami' \
  -e DATABASE_TYPE=postgresql \
  ghcr.io/umami-software/umami:postgresql-latest

实测回显(心跳 200,启动正常):

✓ DATABASE_URL is defined.
✓ Database connection successful.
✓ Ready in 0ms
{"ok":true}

结论:Prisma 按"最后一个 @"拆分凭据与主机,两种写法实测都能连通;但 URL 编码是官方与 URI 规范推荐写法(密码含 /、#、? 等歧义字符时未编码会破坏解析),生产统一用编码写法。最常见的连接失败是"连接串里的密码与库内真实密码不一致",实测错误形态(密码解析后与库不符):

✗
Invalid `prisma.$queryRaw()` invocation:

Raw query failed. Code: `28P01`. Message: `password authentication failed for user "umami"`

5.2 安全与令牌:APP_SECRET / FORCE_SSL / ALLOWED_FRAME_URLS / TWO_FACTOR_ENCRYPTION_KEY

APP_SECRET(v1.0.0):签发登录令牌与 cache 令牌的密钥,官方要求"每安装实例唯一",生成方式 openssl rand -hex 32。不设置时使用内置默认,多实例会互相认可对方令牌,属安全隐患。

实测验证(同库双实例、不同 APP_SECRET,令牌互不通用):

# A 实例(APP_SECRET=EnvTestSecretA-...,端口 13001)登录拿令牌
TOKEN_A=$(curl -s -X POST http://localhost:13001/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')
echo "token_len=${#TOKEN_A}"

# 令牌在 A 实例可用
curl -s -o /dev/null -w 'A_token_on_A=%{http_code}\n' \
  -H "Authorization: Bearer $TOKEN_A" http://localhost:13001/api/websites

# 同一令牌到 B 实例(APP_SECRET=EnvTestSecretB-...,端口 13002)
curl -s -w '\n' -o /dev/null -w 'A_token_on_B=%{http_code}\n' \
  -H "Authorization: Bearer $TOKEN_A" http://localhost:13002/api/websites

实测回显:

token_len=624
A_token_on_A=200
A_token_on_B=401

结论:APP_SECRET 不同的实例间令牌互不认可(401);更换 APP_SECRET 会使该实例所有已签发令牌立即失效(运维上等价于"全员强制下线")。采集端点 /api/send 不受影响(无登录态)。

FORCE_SSL(v1.0.0):设 1 后所有响应带 Strict-Transport-Security 头,强制浏览器后续走 HTTPS(需前置反代终结 TLS)。ALLOWED_FRAME_URLS(v2.3.0,构建时):空格分隔的 URL 列表,允许这些站点 iframe 嵌入 Umami 控制台。TWO_FACTOR_ENCRYPTION_KEY(v3.3.0):64 位 hex(256 位),未配置时任何用户无法开启 2FA(v3.3.0 起功能存在)。

5.3 采集与追踪:TRACKER_SCRIPT_NAME / COLLECT_API_ENDPOINT / CLIENT_IP_HEADER

TRACKER_SCRIPT_NAME(v1.26.0):把统计脚本从默认 /script.js 改名(.js 后缀可不写,也支持带路径),用于绕过广告拦截器对 umami 关键字的规则。实测(B 实例设 TRACKER_SCRIPT_NAME=analytics):

curl -s -o /dev/null -w 'script.js_on_B=%{http_code}\n'  http://localhost:13002/script.js
curl -s -o /dev/null -w 'analytics.js_on_B=%{http_code}\n' http://localhost:13002/analytics.js
curl -s -o /dev/null -w 'analytics_on_B=%{http_code}\n'    http://localhost:13002/analytics

实测回显:

script.js_on_B=200
analytics.js_on_B=200
analytics_on_B=200

三个路径都 200——改名后新路径生效,但默认路径并不因此关闭(实测 /script.js 与 /analytics、/analytics.js 内容 MD5 完全一致:7edb400174f8178e695beb2ad82c40b4)。页面嵌码时改用新名:

<script defer src="http://<host>:13002/analytics.js" data-website-id="..."></script>

COLLECT_API_ENDPOINT(v1.34.0):把采集端点从默认 /api/send 改走自定义路由。实测(E 实例设 COLLECT_API_ENDPOINT=/collect-test):

curl -s -o /dev/null -w 'collect=%{http_code}\n' -X POST http://localhost:13007/collect-test \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0' \
  -d '{"type":"event","payload":{"website":"bd69fdbf-f8bd-48c3-93d4-877c51c93fb4","hostname":"demo.example.com","language":"zh-CN","screen":"1920x1080","url":"/via-custom-endpoint"}}'

curl -s -o /dev/null -w 'api_send=%{http_code}\n' -X POST http://localhost:13007/api/send \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0' \
  -d '{"type":"event","payload":{"website":"bd69fdbf-f8bd-48c3-93d4-877c51c93fb4","hostname":"demo.example.com","language":"zh-CN","screen":"1920x1080","url":"/x"}}'

实测回显:

collect=200
api_send=404

与脚本改名不同:端点改名后默认 /api/send 彻底关闭(404),浏览器脚本与自建上报都要改走新路由。/api/config(无认证)会回显隐私与开关类配置(实测 E 实例,PRIVATE_MODE=1 体现为 privateMode:true):

{"cloudMode":false,"privateMode":true,"sessionDeletionEnabled":true,"telemetryDisabled":false,"updatesDisabled":false}

CLIENT_IP_HEADER(v1.24.0):反代/CDN 场景下从指定请求头取客户端 IP;不设时 Umami 取 TCP 连接来源 IP(拿到的将是反代地址)。该参数影响会话识别(IP+UA+hostname 哈希)。实测(C 实例设 CLIENT_IP_HEADER=x-real-ip,同一 UA 连续上报,观察返回的 sessionId 前 8 位):

# 不同 x-real-ip → 不同会话
curl -s -X POST http://localhost:13003/api/send -H 'Content-Type: application/json' \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0" \
  -H 'x-real-ip: 8.8.4.4' \
  -d '{"type":"event","payload":{"website":"a9e10b5a-f4c0-41ec-834f-0775781b064a","hostname":"ip.example.com","language":"zh-CN","screen":"1920x1080","url":"/ip-a"}}'

实测回显(三条分别对应:不同头值→新会话;同头值→同会话;仅 x-forwarded-for 不同→同会话):

-- 同UA + 不同 x-real-ip --
session: a43558e2  visit: 2420aaf2
session: 76dd3e39  visit: 44cf78dc
-- 同UA + 相同 x-real-ip(重复8.8.4.4) --
session: a43558e2  visit: 2420aaf2
-- 同UA + 仅 x-forwarded-for(不同) --
session: a43558e2  visit: 2420aaf2
session: a43558e2  visit: 2420aaf2

结论:设 CLIENT_IP_HEADER=x-real-ip 后,会话标识只随 x-real-ip 变化(x-forwarded-for 被忽略);头值相同时同 IP+UA 判为同一会话。注意头名必须全小写,且要保证该头确实由可信反代注入(客户端可伪造该头时会影响统计真实性)。对应 stats 实测:5 PV / 4 visitors(两个 x-real-ip 各算访客,4 条 x-f-for 上报归属 8.8.4.4 会话)。

💡 技术拓展:反代传真实 IP 的常见头对比——

头注入方特点
X-Real-IPNginx 常用配置单值,由最外层反代设置
X-Forwarded-For事实标准(多级链)逗号分隔,可被客户端伪造首段
CF-Connecting-IPCloudflareCF 出口真实 IP,可信度取决于来源校验
PROXY 协议HAProxy/部分 LB传输层附加,需应用支持

本文实测选 x-real-ip:单值、语义明确,配合"仅信任反代注入"的网络策略最稳妥。

5.4 隐私与数据卫生:DISABLE_TELEMETRY / PRIVATE_MODE / IGNORE_IP / IGNORE_PATHS / REMOVE_TRAILING_SLASH / SALT_ROTATION

DISABLE_TELEMETRY=1(v2.0.0):关闭向官方遥测像素 https://i.umami.is/a.png?v=3.4.0 的匿名版本上报。实测对照:

curl -s http://localhost:13003/telemetry.js | head -c 120

实测回显(未关闭的实例,正常注入像素脚本,节选):

var i = document.createElement("script"); ...
curl -s http://localhost:13004/telemetry.js

实测回显(DISABLE_TELEMETRY=1 实例):

/* telemetry disabled */

PRIVATE_MODE=1(v2.11.0):切断应用所有对外网络请求(遥测、图标服务等全部停止;同套代码里 DISABLE_TELEMETRY || PRIVATE_MODE 命中即关闭遥测,实测 E 实例仅设 PRIVATE_MODE 时 /telemetry.js 同样返回 /* telemetry disabled */)。离线/内网部署必设。

IGNORE_IP(v1.0.0):逗号分隔的 IP/CIDR 排除列表,命中流量不入库(如 IGNORE_IP=192.168.0.1, 10.0.0.0/24)。IGNORE_HOSTNAME(v1.0.0)排除指定主机名,IGNORE_PATHS(v1.0.0)排除路径(官方支持通配,如 /admin*)。三项均在采集阶段过滤,改后无需迁移数据即生效。

REMOVE_TRAILING_SLASH=1(v1.26.0):上报 URL 去尾斜杠,把 /docs/ 与 /docs 归并为同一路径统计。

SALT_ROTATION(v3.1.0,默认 month):匿名会话盐值的轮换周期,可取 day/week/month/year/none。作用:轮换后同一访客(同 IP+UA)会生成新的会话标识,进一步降低长期跟踪能力;设 none 则不轮换(会话连续性最好,跨期归因更稳)。官方默认 month,即"月度轮换"。

5.5 服务器与日志:PORT / HOSTNAME / LOG_LEVEL / DISABLE_UPDATES / DISABLE_UI / DISABLE_ADMIN

PORT(v1.0.0,默认 3000):服务监听端口。实测(D 实例设 PORT=3001,宿主映射 -p 13004:3001):

curl -s http://localhost:13004/api/heartbeat

实测回显:

{"ok":true}

💡 说明:官方文档对 HOSTNAME/PORT 的口径是"非 Docker 环境需用 pnpm run start-env 启动才读取这两项";官方 Docker 镜像的入口脚本会读取 PORT,实测 3001 监听成功。Compose 用户更推荐保持服务内 3000、改宿主侧 -p 映射即可。

DISABLE_UPDATES=1(v1.33.0):关闭控制台"有新版本"检查(离线环境建议,配合 PRIVATE_MODE 更彻底)。DISABLE_UI=1:只保留采集接口、不渲染控制台(把 Umami 当纯接收端时的极简形态)。DISABLE_ADMIN=1:隐藏管理后台入口。LOG_LEVEL:日志级别(info 默认);LOG_QUERY=1(v2.0.0)在开发模式打印 SQL;DEBUG(v2.0.0)按模块开日志(可选值 umami:auth、umami:clickhouse、umami:kafka、umami:middleware、umami:prisma,如 DEBUG=umami:*)。DISABLE_BOT_CHECK=1(v2.0.0)关闭机器人过滤(默认爬虫流量不入库)。DISABLE_LOGIN=1(v1.26.0)关闭登录页(用反代层做认证时配合)。

ENABLE_TEST_CONSOLE=1(v2.0.0):开启 /console 内部测试页(需管理员登录),可在页面手动触发 pageview/event,用于联调埋点。

5.6 缓存与扩展:REDIS_URL / GEO_DATABASE_URL / SKIP_LOCATION_HEADERS / FAVICON_URL / CORS_MAX_AGE / USE_UUIDV7 / MCP_ENABLED

REDIS_URL(v3.0.1,可选):配置后启用缓存与多实例协调特性(官方口径 redis://localhost:6379);不配置则相关特性关闭,单实例无需 Redis。GEO_DATABASE_URL(v2.0.0):MaxMind 兼容 MMDB 下载地址(如 GeoLite2-City.mmdb),用于 IP 地理定位;未配置且无 CDN 地理头时国家维度为空(实测 metrics?type=country 返回 [])。SKIP_LOCATION_HEADERS=1(v2.15.0):忽略 CDN 注入的地理头、强制用本地库(CDN 只给国家不给地区/城市时的正确姿势)。

FAVICON_URL(v2.18.0):站点图标服务,默认 https://icons.duckduckgo.com/ip3/{{domain}}.ico,可换 Google/Clearbit(注意:默认图标服务是外联请求,PRIVATE_MODE 下图标一并停用)。CORS_MAX_AGE(v2.0.0):CORS 预检缓存秒数,默认 86400(24 小时)。USE_UUIDV7=1(v3.0.2):新生成的标识改用 UUIDv7(按时间有序,索引更友好;已有派生标识不变)。MCP_ENABLED=1(v3.4.0):启用 /mcp 的 Model Context Protocol 端点,供 AI 客户端查询统计(默认关闭)。

六、生产配置模板

模板一:小站/内网(2GB 内存、单实例、PostgreSQL 同机):

environment:
  DATABASE_URL: postgresql://umami:强口令@umami-db:5432/umami
  DATABASE_TYPE: postgresql
  APP_SECRET: <openssl rand -hex 32 生成>
  FORCE_SSL: 1
  DISABLE_TELEMETRY: 1
  IGNORE_IP: 10.0.0.0/8,192.168.0.0/16

适用:日均 PV 10 万以内,关注隐私与离线;FORCE_SSL 需前置 HTTPS 反代。

模板二:多实例/大流量(16GB 内存、2 实例、独立 PG、前置 Nginx+Redis):

environment:
  DATABASE_URL: postgresql://umami:强口令@pg-primary:5432/umami
  DIRECT_DATABASE_URL: postgresql://umami:强口令@pg-primary:5432/umami
  DATABASE_TYPE: postgresql
  APP_SECRET: <所有实例保持一致,否则令牌互不认可>
  REDIS_URL: redis://redis:6379
  CLIENT_IP_HEADER: x-real-ip
  GEO_DATABASE_URL: https://example.com/GeoLite2-City.mmdb
  DISABLE_UPDATES: 1
  LOG_LEVEL: info

适用:日均 PV 百万级、需要横向扩容;多实例必须统一 APP_SECRET(5.2 实测不同密钥令牌不互通),REDIS_URL 提供缓存与协调,GEO 库补全地理维度。

七、常见问题

Q1:改了 APP_SECRET 后用户全部掉线? 正常现象。令牌由 APP_SECRET 签发,换密钥即全部失效(实测同库双实例令牌 401 的同源行为),重新登录即可;采集上报不受影响。

Q2:设置了 TRACKER_SCRIPT_NAME 后 /script.js 还能访问? 能。脚本改名是"新增别名"(实测三条路径同内容 200),页面嵌码改用新名即可绕拦截器;而 COLLECT_API_ENDPOINT 是"替换"(实测旧端点 404)。两者语义不同,别混用预期。

Q3:CLIENT_IP_HEADER 设了但会话数不变? 检查三点:头名小写、请求确实带该头、值真的在变。实测中 x-forwarded-for 变化不影响会话(参数只认指定头);若该头由客户端可伪造,统计会被注入脏会话。

Q4:IGNORE_IP 排除了自己但统计还有内网流量? 确认写法(逗号分隔、CIDR 合法)且变量在 umami 服务实例上生效(docker compose up -d 重建过);另注意 IGNORE_IP 过滤的是采集入库,历史数据不会回溯删除。

Q5:SALT_ROTATION 改成 none 有什么影响? 同 IP+UA 的访客在跨月后不再生成新会话标识,跨期报表的"新访客"口径会变少;配合 IGNORE_IP 使用时无额外冲突。默认 month 是官方平衡隐私与统计口径的选择,无特殊需求不建议改。

Q6:MCP /mcp 端点开不了? 需 MCP_ENABLED=1 且为 v3.4.0+(该参数 v3.4.0 引入),改后重建服务;用 MCP 客户端连 http://<host>:<port>/mcp 验证。

八、参考链接