4 min read

告別 Counter.dev,在 VPS 上自架 Umami 網站分析

告別 Counter.dev,在 VPS 上自架 Umami 網站分析

前言

之前一直用 Counter.dev 來追蹤部落格的訪客數據,它夠簡單、免費、注重隱私,但最近發現 Dashboard 突然不計數了,登入後台也看不到新數據。

查了一下才知道,Counter.dev 是一個人用 $5/月的 VPS + Redis 在撐的開源專案,歷史上已經有過好幾次服務中斷(2023 年在 Hacker News 上就有人問過 "Is Counter.dev down?"),免費仔的宿命就是這樣,服務隨時可能消失。

既然我有自己的 VPS,不如直接自架一個穩定的方案,研究了一輪之後,選了 Umami — 開源、輕量、有 API、GitHub 35k+ stars,而且用 Docker 部署超快。

環境

  • VPS:Ubuntu 24.04(已經跑 Ghost CMS + Nginx)
  • Docker + Docker Compose
  • 域名透過 Cloudflare 管理

安裝 Docker

如果你的 VPS 還沒裝 Docker:

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

裝完登出再登入,讓 group 生效。

部署 Umami

建立專案目錄

mkdir ~/umami && cd ~/umami

產生密碼和 salt

DB_PASS=$(openssl rand -hex 16)
APP_SECRET=$(openssl rand -hex 32)
echo "DB_PASS: $DB_PASS"
echo "APP_SECRET: $APP_SECRET"

記下這兩個值,等等要用。

建立 docker-compose.yml

services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    ports:
      - "3001:3000"
    environment:
      DATABASE_URL: postgresql://umami:<你的DB_PASS>@db:5432/umami
      APP_SECRET: <你的APP_SECRET>
    depends_on:
      db:
        condition: service_healthy
    restart: always

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: <你的DB_PASS>
    volumes:
      - umami-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U umami"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: always

volumes:
  umami-db:

啟動

docker compose up -d

等大約 15 秒讓 Next.js build 完成,然後確認服務有活:

curl -s -o /dev/null -w "%{http_code}" http://localhost:3001
# 應該回 200

設定 Nginx 反向代理

新增 Nginx 設定檔

sudo tee /etc/nginx/sites-available/analytics.yourdomain.com.conf << 'EOF'
server {
    listen 80;
    server_name analytics.yourdomain.com;

    location / {
        proxy_pass http://localhost:3001;
        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;
        proxy_set_header Host $host;
    }
}
EOF

啟用 + 測試

sudo ln -s /etc/nginx/sites-available/analytics.yourdomain.com.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

DNS 設定

到你的 DNS 管理介面(我用 Cloudflare),加一筆 A record:

Name Type Value Proxy
analytics A 你的VPS IP DNS only(灰色雲)
⚠️ 先關掉 Cloudflare Proxy(灰色雲),因為 certbot 需要直連 VPS 做 HTTP 驗證。

確認 DNS 生效:

dig analytics.yourdomain.com +short
# 應該回你的 VPS IP

上 SSL

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d analytics.yourdomain.com

一路 Yes 下去就好,certbot 會自動改 Nginx 設定。

登入 Umami

打開 https://analytics.yourdomain.com

預設帳密:

  • Username: admin
  • Password: umami

登入後馬上改密碼!(Settings → Profile)

加入網站 + 取得 Tracking Code

  1. Settings → Websites → Add website
  2. 填入你的網站域名
  3. 拿到 tracking script:
<script defer src="https://analytics.yourdomain.com/script.js" data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>

整合到 Ghost CMS

Ghost Admin → Settings → Code injection → Site Header

  1. 刪掉舊的 Counter.dev script(如果有的話)
  2. 貼上 Umami 的 tracking script
  3. Save

開一個無痕視窗訪問你的網站,回 Umami Dashboard 看有沒有收到數據。

備份

既然是自架的,備份就是你自己的責任了,Umami 的數據存在 PostgreSQL 裡,一行指令就能 dump:

docker compose -f ~/umami/docker-compose.yml exec -T db pg_dump -U umami umami > ~/umami-backup-$(date +%F).sql

如果你已經有自動備份腳本(像我用 cron + rclone 同步到 Google Drive),直接加一行進去就好。

更新 Umami

之後有新版本,兩行搞定:

cd ~/umami
docker compose pull && docker compose up -d

Counter.dev vs Umami 比較

Counter.dev Umami
費用 免費 免費(自架)
穩定性 ⚠️ 一個人維護的小專案 ✅ 活躍開源社群,20k+ stars
API ❌ 沒有公開 API ✅ 完整 REST API
資料控制 存在別人的 Redis 存在你自己的 PostgreSQL
廣告阻擋 容易被擋 自架子域名不會被擋
Dashboard 極簡 功能完整、支援多網站

結論

整個過程大概 15 分鐘,如果你已經有 VPS 跑其他服務(像 Ghost CMS),多開一個 Umami 的 Docker container 幾乎不佔什麼額外資源,比起依賴免費第三方服務隨時可能掛掉,自架一個穩定可控的分析工具,絕對值得。