ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 Umami 和 PostgreSQL 自建网站统计:数据自主可控还能远程看

用 Umami 和 PostgreSQL 自建网站统计:数据自主可控还能远程看 做个人站点或者小团队项目的时候流量统计是个绕不开的需求。最早我一直在用第三方统计服务页面里塞一段 JS 就能看到 PV、UV、来源、设备分布。方便是真方便但时间久了会冒出几个不舒服的点数据不在自己手里想导出原始记录做二次分析很麻烦免费额度和保留周期有限制某些服务在国内访问稳定性也一般。于是我想干脆自己搭一套能长期跑、数据落在我自己的数据库里、还能随时远程打开看。最后选的是 Umami。它是一个开源的网站分析工具定位和第三方统计类似但可以自托管。后端支持多种数据库我这边用 PostgreSQL因为服务器上本来就有实例备份和运维都现成。下面把整个搭建过程和我实际踩到的点写清楚。先弄清楚 Umami 是什么、适合谁Umami 的定位很明确轻量、注重隐私的网站分析。它不需要 Cookie 做跨站追踪默认不采集个人身份信息前端那段脚本也很小。它提供的指标是常规的那一套——访问量、独立访客、页面排行、来源、浏览器、操作系统、国家地区等。它不适合什么场景也要说清楚。如果你需要极细粒度的用户行为路径、漏斗、热图、A/B 实验那 Umami 不是这类工具它更接近统计面板而不是用户行为分析平台。对我这种只想知道哪些文章有人看、流量从哪来的需求够用。关于版本Umami 迭代比较快v2 之后对数据库和配置项做过调整官方文档也在持续更新。我下面写的是我实际部署时使用的思路和配置方式具体版本号建议以你拉取镜像或 clone 仓库时看到的为准我这边没有把某个具体小版本号当成固定事实写死。技术选型为什么是 PostgreSQL 而不是默认数据库Umami 支持 MySQL 和 PostgreSQL。我选 PostgreSQL 主要两个原因一是服务器上已有实例不用额外装一套数据库二是备份脚本、监控都已经围绕 PostgreSQL 建好了复用成本最低。简单对比一下几种数据库选择方案优点缺点适用场景SQLite零配置单文件部署最简单并发写入弱多实例共享不方便个人单机、流量很小的站点MySQL生态成熟托管服务多需要单独维护实例已有 MySQL 运维体系的团队PostgreSQL功能强备份监控方案成熟JSON 支持好需要维护实例配置略重已有 PG 实例、需要长期稳定运行如果你的站流量很小、只有一台机器、不想碰数据库运维SQLite 其实是最省事的选择。我这边纯粹是复用现有 PG 实例不代表 PG 一定比 SQLite 好。部署方式容器还是手动装Umami 官方推荐用 Docker 部署社区也维护了官方镜像。我倾向容器因为升级和回滚都干净环境变量注入也直接。手动用 Node.js 跑当然可以但要自己管 Node 版本、依赖、进程守护长期维护麻烦。我实际用的是 Docker Compose把 Umami 应用和它的数据库分开管理。因为数据库我复用的是外部 PG 实例所以 compose 里只放应用本身数据库连接通过环境变量传进去。先准备数据库。登录 PostgreSQL建一个独立库和独立用户不要用超级用户跑应用-- 用 psql 连上你的 PostgreSQL 实例后执行CREATEDATABASEumami;CREATEUSERumami_userWITHENCRYPTED PASSWORD换成你自己的强密码;GRANTALLPRIVILEGESONDATABASEumamiTOumami_user;-- PostgreSQL 15 及以上public schema 默认权限收紧需要额外授权\c umamiGRANTALLONSCHEMApublicTOumami_user;这里有个容易忽略的地方PostgreSQL 15 开始普通用户对 public schema 的默认建表权限被收紧了。如果你用的是 PG 15 或更高版本只做GRANT ALL PRIVILEGES ON DATABASE可能不够应用建表时会报权限错误。上面那条GRANT ALL ON SCHEMA public就是为这个准备的。这一点我在 PG 15 上实际遇到过PG 14 及以下通常不需要。【踩坑提醒】如果你不确定自己的 PG 版本用SELECT version();确认一下别照抄配置后卡在权限问题上。用 Docker Compose 把应用跑起来数据库准备好之后写一个 compose 文件。下面是我用的结构环境变量里的值都换成你自己的# docker-compose.ymlservices:umami:image:ghcr.io/umami-software/umami:postgresql-latestcontainer_name:umamirestart:unless-stoppedports:-127.0.0.1:3000:3000environment:DATABASE_TYPE:postgresqlDATABASE_URL:postgresql://umami_user:你的密码数据库地址:5432/umamiAPP_SECRET:换成一串足够长的随机字符串healthcheck:test:[CMD-SHELL,wget -qO- http://localhost:3000/api/heartbeat || exit 1]interval:30stimeout:5sretries:3几个点解释一下为什么这么写。端口映射我写的是127.0.0.1:3000:3000而不是3000:3000。意思是只监听本机回环地址外部不能直接访问 3000 端口必须经过反向代理。这样避免把应用端口直接暴露到公网反向代理层再做 HTTPS 和访问控制。如果你打算直接对外暴露可以改但我不建议。APP_SECRET是 Umami 用来签名会话之类的密钥一定要换成随机值别用示例里的占位符。可以用openssl rand -hex 32生成。镜像 tag 我写的是postgresql-latest。这里要说明latest这类标签意味着每次拉取可能拿到不同版本升级时行为可能变化。生产环境更稳妥的做法是锁定一个具体版本 tag。我为了演示方便用了 latest你如果要长期跑建议查一下当前可用的具体版本标签并固定下来。这一点我没有把所有 tag 都验证过以官方镜像仓库列出的为准。healthcheck 里用到了/api/heartbeat这个路径。这是我部署时使用的健康检查端点但 Umami 不同版本端点可能调整如果你发现容器一直显示 unhealthy先确认这个路径在当前版本是否还存在。启动dockercompose up-ddockercompose logs-fumami日志里如果看到数据库连接成功、迁移完成之类的信息基本就起来了。Umami 首次启动会自动建表所以数据库用户得有建表权限这也是前面要授权 schema 的原因。反向代理和远程访问应用起来后默认只能在服务器本机访问。要远程看得经过反向代理。我用的是 Nginx配置大致如下server { listen 443 ssl; server_name stats.example.com; ssl_certificate /etc/letsencrypt/live/stats.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/stats.example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }X-Forwarded-For和X-Forwarded-Proto这两个头比较关键。Umami 要靠它们识别真实访客 IP 和协议否则统计到的来源 IP 可能全是代理地址。不同反向代理Caddy、Traefik头名称基本一致按各自文档配置即可。远程访问的安全问题值得单独说。Umami 后台默认是账号密码登录第一次部署后要尽快进后台改掉默认管理员账号。默认账号密码官方文档有说明通常是admin/umami这个一定要改否则等于把后台敞开。如果你还担心可以在 Nginx 层再加一层 Basic Auth或者限制来源 IP。我这边是改密码加 HTTPS够个人用。接入站点并验证数据登录后台后添加一个网站Umami 会生成一段追踪脚本类似scriptdefersrchttps://stats.example.com/script.jsdata-website-id你的站点ID/script把data-website-id换成后台生成的那串 ID脚本地址换成你自己的域名然后放到网站所有页面的head或/body前。放好之后刷新几个页面回到 Umami 面板看是否出现实时数据。如果没数据按顺序排查浏览器控制台看script.js是否 404确认脚本地址正确。Network 面板看请求是否发出、返回状态码。确认data-website-id和后台站点 ID 一致。如果站点用了 CSP内容安全策略确认脚本域名在允许列表里否则会被浏览器拦掉。反向代理日志看请求有没有到 Umami。这里我想强调一点追踪脚本的请求能不能成功取决于你的统计域名是否稳定可访问。如果stats.example.com本身挂了或者被墙脚本加载失败数据自然收不到。所以自建统计也有它自己的可用性要求别以为自建就一劳永逸。数据备份和长期维护数据在自己手里备份就是自己的责任了。PostgreSQL 的备份我用pg_dump# 每天定时备份保留最近 7 天pg_dump-h数据库地址-Uumami_user-dumami-Fc\-f/backup/umami_$(date%F).dump-F c是自定义格式方便用pg_restore恢复。把这条放进 cron 或者 systemd timer配合清理旧文件的逻辑就行。恢复的时候记得先建好空库和用户。升级 Umami 的话先备份数据库再拉新镜像重启。因为它启动时会跑数据库迁移迁移失败回滚比较麻烦所以备份是前提。我升级前都会先 dump 一份这个习惯救过我一次——某次迁移中途报错直接回滚镜像加恢复备份就解决了。这套方案的真实取舍用下来有几点体会。好处很直接数据在自己的 PG 里想查什么直接写 SQL不用受第三方接口限制没有额度、保留周期的约束面板访问速度取决于自己服务器不受第三方波动影响。代价也要认你得维护一台服务器、一个数据库、一个反向代理还要自己做备份和升级。如果只是个人博客、流量不大、又不想运维继续用第三方统计可能更省心。自建统计的价值在于掌控但这个掌控是要花运维成本换的。另外一个现实问题是Umami 作为分析工具功能深度比不上专业商业产品。它给你的是核心指标不是全套行为分析。选它之前先想清楚自己到底要看什么数据。最后这套搭下来核心步骤其实就四步准备 PostgreSQL 库和用户、用 Docker 跑 Umami 并注入数据库连接、Nginx 做反向代理和 HTTPS、接入追踪脚本验证数据。最容易出问题的地方一是 PG 15 以上的 schema 权限二是反向代理没传转发头导致 IP 统计不准三是默认管理员密码没改。这三点我在实际部署中都特别留意过。如果你也在纠结要不要把统计迁回自己手里我的建议是先评估运维成本能不能接受能接受再动手。数据库选型、部署方式这些细节按你现有的基础设施来定就好没有标准答案。备用标题Umami 自建网站统计实战PostgreSQL 数据库配置与远程访问把网站流量数据拿回自己手里Umami 加 PostgreSQL 部署记录自托管网站分析平台怎么搭Umami 配合 PostgreSQL 的完整流程从第三方统计到自建用 Umami 和 PostgreSQL 搭建访问分析面板Umami 部署避坑PostgreSQL 权限、反向代理和追踪脚本排查
返回列表