Umami是个个人网站站点数据分析的工具,支持自己部署,使用他们的服务器好像最多可以跟踪三个站点。我还试过使用Plausible,但是对我而言有一点重,使用之后System Load增加了许多。

部署

  • 创建docker-compose.yml,根据自己的情况修改,这里我接入了cloudflared的网络,就可以实现公网访问了。

    services:
      umami:
        container_name: umami
        image: ghcr.io/umami-software/umami:postgresql-latest
        environment:
          DATABASE_URL: postgresql://<db_username>:<db_password>@umami-db:5432/umami
          DATABASE_TYPE: postgresql
          APP_SECRET: 
        depends_on:
          umami-db:
            condition: service_healthy
        init: true
        restart: unless-stopped
        networks:
          - umami
          - cloudflared
    
      umami-db:
        container_name: umami-db
        image: postgres:15-alpine
        environment:
          POSTGRES_DB: umami
          POSTGRES_USER: 
          POSTGRES_PASSWORD: 
        volumes:
          - ./data:/var/lib/postgresql/data
        restart: unless-stopped
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
          interval: 5s
          timeout: 5s
          retries: 5
        networks:
          - umami
    
    networks:
      cloudflared:
        external: true
      umami:
        name: umami
        driver: bridge
    
  • 可以使用OpenSSL生成secret

    openssl rand -base64 32
    
  • 启动容器

    docker compose up -d
    
  • 在反向代理添加域名,umami自动监听3000端口

    Subdomain: data
    Domain: your_domain
    Type: HTTP
    URL: umami:3000
    
  • 默认用户名为admin,默认密码为umami,可以直接用Web页面修改用户名密码

  • 添加网站后,在Setting → Tracking Code可以得到跟踪代码,我使用的个人网站主题为Hugo,将跟踪代码粘贴到layouts/partials/head.html

最终效果还是很好看的,只是可惜之前的数据就没有记录了,可以在这里预览:Umami

Umami

嵌入到博客前端

实现这个需要使用一个三段式的Proxy,前端脚本嵌入代码script.js,代码访问umami-api的接口,接口服务使用umami的token调用umami,得到数据后返回前端,前端可以根据初始值然后显示出来。我自己写了个小服务:GitHub - Kyxie/umami-api

  • 在Umami中创建一个Team,将博客转移到Team中

  • 创建一个权限比较低的新用户,比如view only,把这个新用户加入到新创建的Team,我们最好不要直接使用高权限用户,因为万一token泄露很危险

  • 使用PostWoman或curl发送请求,username使用新用户的用户名和密码

    curl -X POST https://umami_url/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"username":"username", "password":"password"}'
    
  • 响应体中我们能得到一个token

  • 在Cloudflared中新建一个hostname,我们需要让umami-api支持公网访问

    Subdomain: umami-api
    domain: your_domain
    type: HTTP
    URL: umami-api:3001
    
  • 创建一个.env

    UMAMI_URL=[your_umami_url]
    UMAMI_TOKEN=[your_token]
    UMAMI_WEBSITE_ID=[your_website_id]
    CORS_ALLOW_ORIGIN=[your_blog_url]
    
    • UMAMI_URL是Umami的URL,由于API和Umami在一个容器网络,可以填容器名称(http://umami:3000)
    • UMAMI_TOKEN是刚才生成的token
    • UMAMI_WEBSITE_ID是Umami中网站的id
    • CORS_ALLOW_ORIGIN是允许访问服务的url(比如要嵌入的博客),可以不止一个,中间用逗号隔开
  • 创建docker-compose.yml

     umami-api:
        image: kyxie/umami-api:latest
        container_name: umami-api
        env_file: .env
        restart: unless-stopped
        networks:
          - umami
          - cloudflared
    

    直接把这一段放到umami的stack中,加入cloudflared容器网络

  • 启动容器

    docker compose up -d
    

Trouble Shoot

  • 如果script.js没有变化,可能是浏览器缓存了,清空一下缓存试试
  • 如果清空浏览器缓存还是没有变化,可能还是cloudflared缓存了,进入cloudflare → 域名 → Caching → Configuration → Purge Cache → Custom Purge → 输入script.js的url即可