之前了解过有 51la 这种第三方的网站统计分析工具,不想用,偶然看到这个开源自部署的,就弄了一个,umami 官网。
dockerhub 地址,用的这个老哥的镜像,跟着说明来就完事了。
- 老朋友 docker-compose 启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| version: '3' services: umami: image: ghcr.io/umami-software/umami:postgresql-latest ports: - "3956:3000" environment: DATABASE_URL: postgresql://umami:${ADMIN_PASSWORD}@db:5432/umami DATABASE_TYPE: postgresql APP_SECRET: ${SECRET_KEY_BASE} depends_on: - db restart: always networks: - umami-network container_name: umami_app db: image: postgres:15-alpine environment: POSTGRES_DB: umami POSTGRES_USER: umami POSTGRES_PASSWORD: ${ADMIN_PASSWORD} volumes: - ./umami-db-data:/var/lib/postgresql/data restart: always networks: - umami-network container_name: umami_db
networks: umami-network:
|
里面${XXX}
的变量你可以写在同目录.env
文件更安全,也可以直接写进 docker-compose。
docker-compose up -d
启动,这个过程有点慢,忘记开全局魔法了。成功启动之后,访问端口3956
即可,初始账号admin
,初始密码umami
,进去可以改成中文然后改一下密码。
- 链接到自己的网站。
在管理界面添加网站绑定域名,即可获得一个script
脚本,添加到网页的header
部分即可。
我平时自己开发网站的主题是直接服务器上改的,所以会不停的刷新网页,这样会导致浏览量会加太多,都是自己刷的,没有意义。所以加入了一个 cookie 验证的办法。
首先,F12
进入 edge 浏览器开发者工具,在应用程序的Cookies
栏添加一个cookie
,名称就是disableUmami
,值可以设置为true
或任何非空字符串。将路径设置为/
。
然后网页头部的脚本套上一个判断,这样访客基本都是货真价实的啦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script> function checkCookie(name) { return document.cookie.split(';').some(function (item) { return item.trim().startsWith(name + '='); }); }
if (!checkCookie('disableUmami')) { var script = document.createElement('script'); script.async = true; script.src = "http://{{你的umami域名}}/script.js"; script.setAttribute("data-website-id", "{{你的网站id}}"); document.head.appendChild(script); } </script>
|
- 调用 API 前台显示
目前这个样子只是在umami
后台可以看到统计数据,如果有些数据想展示到前端,umami
提供了 API,文档很详细。不过要注意的是请求数据之前首先要请求TOKEN
,下面是一个获取网站在线人数的脚本,这个只在网页刷新时更新,目前还没有做实时更新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <div class="webinfo-item"> <?php // Umami API 的基本信息 $loginUrl = 'http://{{你的umami域名}}/api/auth/login'; // 登录端点 $activeUsersUrl = 'http: $username = '{{Umami 用户名}}'; $password = '{{Umami 密码}}';
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $loginUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('username' => $username, 'password' => $password))); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$response = curl_exec($ch); if (curl_errno($ch)) { echo '登录请求错误:' . curl_error($ch); curl_close($ch); exit; }
$authResponse = json_decode($response, true); if (!isset($authResponse['token'])) { echo '无法获取授权令牌'; curl_close($ch); exit; } $token = $authResponse['token']; curl_close($ch);
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $activeUsersUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token));
$response = curl_exec($ch); if (curl_errno($ch)) { echo '获取在线用户数请求错误:' . curl_error($ch); curl_close($ch); exit; } curl_close($ch);
$activeUsers = json_decode($response, true); ?>
<div class="item-name">当前在线用户数 :</div> <div class="item-count"> <?php if (isset($activeUsers[0]['x'])) { echo $activeUsers[0]['x']; } else { echo "无法获取"; } ?> </div> </div>
|
后来发现自己服务器 2G 内存好像不是很够用,umami 的 app 容器居然就占了 200 多 M,于是把 app 改为部署到 vercel 了,毕竟网站统计只是给自己看的。好在之前 umami_db 的数据是挂载到本地的,这次迁移几乎不会丢失之前的数据。
- 关闭本地两个容器,重启 db 容器。
原来本地两个容器只有他们之间可以通信,没有暴露端口到宿主机,现在需要部署在 vercel 的 app 层和在我服务器的 db 层通信,所以重启 db 容器,暴露端口,命令如下。
1 2 3 4 5 6 7 8 9
| docker run -d \ --name umami_db \ -e POSTGRES_DB=umami \ -e POSTGRES_USER=umami \ -e POSTGRES_PASSWORD='{{密码}}' \ -v ./umami-db-data:/var/lib/postgresql/data \ -p {{自己设一个端口}}:5432 \ --restart always \ postgres:15-alpine
|
- 部署 app 层到 vercel。
官方给出了一键部署,很方便,点击这里。
登录自己的 github 账号,新建一个 umami 仓库。
关键在于配置这个环境变量,其中包含的变量来自上面拆创建 db 容器时的数据库相关参数。
1
| DATABASE_URL:postgres://{{POSTGRES_USER}}:{{POSTGRES_PASSWORD}}@{{你的服务器IP地址}}:{{db容器端口}}/{{POSTGRES_DB}}
|
如果DATABASE_URL
配置正确,vercel 就会编译部署成功,登录进去就可以继续访问 db 数据库的数据啦。