注:文章内容关于部署过分已过时,最新部署教程参见:家庭数据中心系列 当下最新版umami(2.11.3)详细搭建教程,部署成功后的初始化操作可以仍然参考这篇文章。
Contents
前言
自从博客上线了以后,陆续研究了一堆相关技术:健康监测(uptime-kuma),故障消息推送(bark),web应用防火墙(长亭雷池)等,但是却缺乏一个直观的查看访问来源的方式。
讲道理,其实长亭雷池到可以简单看看,如下:
但是一来这个太粗犷,毕竟不是专门干这个的,二来这个页面也不能单独拿出来。。。
在网上搜了下,发现了Umami这个工具:Umami 是一款简单易用、自托管的开源网站访问流量统计分析工具,Umami 不使用 Cookie,不跟踪用户,且所有收集的数据都会匿名化处理,符合 GDPR 政策,资源占用很低,虽然功能简单,但分析的数据内容很丰富。
看介绍不错,就决定用它了,搭建完成后最终效果如下:
部署Umami
Umami需要用到数据库,默认Umami支持2种数据库:mysql和postgresql。如果按我以前的文章的惯例,我一般能利旧mariadb的肯定是利旧的,但是umami有点特殊:它使用的数据库需要特殊的初始化,空白数据库还不行,专门初始化就显得折腾了(简单才是王道),所以本篇文章破例使用docker-compose的方式来搭建,我是将umami部署在腾讯云的轻量服务器上。
创建 docker-compose.yml文件
在对应的目录里创建docker-compose.yml文件,我是在/docker/umami:
mkdir -p /docker/umami
cd /docker/umami
vim docker-compose.yml
docker-compose.yml的内容如下:
---
version: '3'
services:
umami:
image: ghcr.io/mikecao/umami:postgresql-latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: replace-me-with-a-random-string
TRACKER_SCRIPT_NAME: random-string.js
depends_on:
- db
restart: always
networks:
- public-net
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
volumes:
- ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
- ./data:/var/lib/postgresql/data
restart: always
networks:
- public-net
networks:
public-net:
external: true
有4个需要注意的地方:
1、需要提前创建sql目录和data目录:
mkdir /docker/umami/sql
mkdir /docker/umami/data
2、networks部分
我因为本来就有public-net这个bridge网络,所以这里是以下结构:
services:
umami:
networks:
- public-net
db:
networks:
- public-net
networks:
public-net:
external: true
如果是新建的网络,这里应该是类似:
services:
umami:
networks:
- default
db:
networks:
- default
networks:
default:
name: public-net
3、注意的是宿主机的3000端口是否被占用,如果被占用则改成一个没用的端口即可。
4、创建schema.postgresql.sql文件
注意在db部分有个挂载到容器内的文件schema.postgresql.sql
,这是一个sql的脚本文件,就是我前面提到的需要提前初始化数据库的内容,我们需要手动创建这个文件:
vim /docker/umami/sql/schema.postgresql.sql
粘贴进如下内容并保存退出:
drop table if exists event;
drop table if exists pageview;
drop table if exists session;
drop table if exists website;
drop table if exists account;
create table account (
user_id serial primary key,
username varchar(255) unique not null,
password varchar(60) not null,
is_admin bool not null default false,
created_at timestamp with time zone default current_timestamp,
updated_at timestamp with time zone default current_timestamp
);
create table website (
website_id serial primary key,
website_uuid uuid unique not null,
user_id int not null references account(user_id) on delete cascade,
name varchar(100) not null,
domain varchar(500),
share_id varchar(64) unique,
created_at timestamp with time zone default current_timestamp
);
create table session (
session_id serial primary key,
session_uuid uuid unique not null,
website_id int not null references website(website_id) on delete cascade,
created_at timestamp with time zone default current_timestamp,
hostname varchar(100),
browser varchar(20),
os varchar(20),
device varchar(20),
screen varchar(11),
language varchar(35),
country char(2)
);
create table pageview (
view_id serial primary key,
website_id int not null references website(website_id) on delete cascade,
session_id int not null references session(session_id) on delete cascade,
created_at timestamp with time zone default current_timestamp,
url varchar(500) not null,
referrer varchar(500)
);
create table event (
event_id serial primary key,
website_id int not null references website(website_id) on delete cascade,
session_id int not null references session(session_id) on delete cascade,
created_at timestamp with time zone default current_timestamp,
url varchar(500) not null,
event_type varchar(50) not null,
event_value varchar(50) not null
);
create index website_user_id_idx on website(user_id);
create index session_created_at_idx on session(created_at);
create index session_website_id_idx on session(website_id);
create index pageview_created_at_idx on pageview(created_at);
create index pageview_website_id_idx on pageview(website_id);
create index pageview_session_id_idx on pageview(session_id);
create index pageview_website_id_created_at_idx on pageview(website_id, created_at);
create index pageview_website_id_session_id_created_at_idx on pageview(website_id, session_id, created_at);
create index event_created_at_idx on event(created_at);
create index event_website_id_idx on event(website_id);
create index event_session_id_idx on event(session_id);
insert into account (username, password, is_admin) values ('admin', '2b10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa', true);
先拉取镜像:
docker pull ghcr.io/mikecao/umami:postgresql-latest
docker pull postgres:15-alpine
国内拉取速度会很慢,不过如果有使用科学或者魔法的环境,可以考虑使用proxychains,参见我的另一篇文章:家庭数据中心系列 强大的局部代理工具:proxychains(cli)
拉起容器
cd /docker/umami
docker-compose up -d
容器正常工作的话,通过http://宿主机IP:3000
即可打开登录页面:
默认用户名:admin,默认密码:umami
进入后默认英文,点击红框按钮修改语言成中文简体:
添加反向代理
通过反向代理使用公网域名发布umami,我是用宝塔linux面板,其他的1panel、NPM等都可以,大家根据各自熟悉的方式配置即可,随后即可用域名访问umami,具体配置步骤参见文章:linux面板系列 配置反向代理并使用非443端口进行发布。
配置umami
添加需要统计的网站
通过域名方式登录umami。
点击”设置“-”添加网站“:
然后属于需要监测网站的名称、域名,如果想要让别人看也看到部分信息,点击红框中的”启用共享链接“,然后点击保存:
添加完成后界面如下:
上图红框中的按钮为”获取共享链接“,可以让别人看到你站点的部分统计情况,不过现在看不到信息,还需要将追踪代码嵌入到要监测的网站中才能生效。
获取追踪代码
点击”设置”中点击红框按钮来获取追踪代码:
弹出如下界面:
点击下方的复制按钮即可获得追踪代码。
插入追踪代码
这个对于不同的建站方式,配置就不同了。我建站用的是wordpress,并且使用了Argon主题,可以直接在Argon的”页头脚本“选项直接配置,如下:
如果是其他方式,可以找类似于header.php,然后放在<head></head>
标签之间就行了。
优化项
如果国家/地区出现未知,既统计不到来源,可以在反向代理配置里增加以下代码:
location = /api/collect
{
proxy_pass http://ip:端口/api/collect;
proxy_buffering on;
proxy_http_version 1.1;
proxy_ssl_session_reuse off;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP remote_addr;
proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
}
IP端口替换成你的配置即可。
最终效果见本站”顶部菜单”-“其他功能”-“流量监控”: