Docker ComposeとPostgreSQLによるUmami Analyticsの構築手順:GA4に代わるセルフホスト型アクセス解析

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

1. なぜGoogle Analytics 4(GA4)は小規模サイトに向いていないのか?

昨日のブログ閲覧数や訪問元の流入経路をさっと確認したいだけなのに、GA4を開くと無数のサブメニューに迷わされ、煩雑なレポート設定を強いられ、さらにはデータ反映までに24〜48時間も待たされる——。GA4は複雑なファネル分析を必要とする大企業向けに設計されており、シンプルさを求める個人サイトや小規模Webサイトには明らかにオーバースペックです。

さらに、パフォーマンスとプライバシーの面でも大きな課題があります:

  • Webサイトの表示遅延: Googleのgtag.jsライブラリは約45KB(展開時は100KB近く)あり、モバイル環境におけるCore Web Vitalsスコアを直接引き下げる原因になります。
  • 煩わしいCookie同意バナー: GDPR対応のため、記事を開いた瞬間に画面の3分の1を覆うような巨大なCookie同意バナーの設置を余儀なくされます。

私たちが本当に必要としているのは、直感的なダッシュボードだけです。「誰が読んでいるのか? どのリンクから流入したのか? どの記事が一番人気なのか?」 そしてこれらのデータはすべて手元で完全に管理でき、瞬時に読み込まれ、訪問者を不快にさせないものであるべきです。

2. アーキテクチャ構成:Umami + Docker Compose + PostgreSQL

Umamiはこれらの課題をスマートに解決します。このエコシステム全体は、以下の3つの要素でスムーズに連携して動作します:

  • Umami Analytics: Next.jsで構築された管理ダッシュボード。Umamiのトラッキングコードはわずか約2KBで、GA4の20分の1近く軽量です。Cookieを使用せず、IPアドレスとUser-Agentから24時間ごとにローテーション生成されるハッシュ値でユニーク訪問者を識別するため、同意ポップアップを表示することなくGDPRに完全準拠できます。
  • PostgreSQL 15: すべてのページビュー(pageview)とイベント(event)を保存するデータベース。データはすべて自身のサーバーのストレージ内に完結し、外部の第三者サーバーへ送信されることはありません。
  • Docker Compose: Node.jsのインストールや手動ビルドを不要にするオーケストレーションツール。Umamiのスタック全体とデータベースが1つのファイルにパッケージ化され、コマンド1発で起動できます。

この組み合わせのメモリ消費量はわずか180MB〜250MB程度です。1 vCPU / 1GB RAM程度の安価なVPS(月額数百円レベル)であっても、月間数十万PV規模のWebサイトを十分に処理できます。

3. Linux VPSでのUmami構築手順

Docker EngineおよびDocker Composeプラグイン(v2)がインストール済みのUbuntuまたはDebianサーバーを用意します。準備ができたら、以下の手順を順番に進めてください。

ステップ1:プロジェクトディレクトリの作成

VPSのターミナルを開き、設定ファイルを格納するための専用ディレクトリを作成します:

mkdir -p ~/umami-analytics && cd ~/umami-analytics

ステップ2:docker-compose.ymlの作成

ファイルを作成する前に、APP_SECRET用のランダムな秘密文字列をコマンドで生成しておきます:

openssl rand -hex 32

続いて、docker-compose.ymlファイルを作成します:

nano docker-compose.yml

以下の標準設定を貼り付けます。my_strong_db_passwordは独自のデータベースパスワードに、YOUR_GENERATED_SECRETは先ほど生成したHEX文字列に忘れずに置き換えてください:

services:
  umami-db:
    image: postgres:15-alpine
    container_name: umami_postgres
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami_user
      POSTGRES_PASSWORD: my_strong_db_password
    volumes:
      - umami-db-data:/var/lib/postgresql/data
    restart: always

  umami-app:
    image: ghcr.io/umami-software/umami:postgresql-latest
    container_name: umami_server
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami_user:my_strong_db_password@umami-db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: YOUR_GENERATED_SECRET
    depends_on:
      - umami-db
    restart: always

volumes:
  umami-db-data:

ステップ3:コンテナの起動とログの確認

イメージをプルし、コンテナをバックグラウンドで起動します:

docker compose up -d

初回起動時、コンテナはデータベーステーブルを初期化するためのマイグレーションスクリプトを自動実行します。この処理には約20〜40秒かかります。ログから進捗を確認できます:

docker compose logs -f umami-app

Ready in ...msという文字列とポート3000でのリッスン通知が表示されれば、アプリケーションの準備は完了です。

ちょっとしたTips:Dockerのログをデバッグする際や、Umamiから返されるJSONデータをAPIでテストする際は、toolcraft.app/ja/tools/developer/json-formatterなどのオンラインツールに貼り付けると、手軽にフォーマットしてデータ構造を確認できます。

ステップ4:ログインと初期パスワードの即時変更

ブラウザを開き、http://VPSのIPアドレス:3000にアクセスします。システムのデフォルトアカウントは以下の通りです:

  • Username: admin
  • Password: umami

ログインに成功したら、すぐにSettings > Profileへ移動してパスワードを変更してください。インターネット上の自動スキャンボットがデフォルトパスワードを狙ってポート3000を常に探索しているため、このステップは絶対にスキップしないでください。さらにセキュリティを高めたい場合は、Docker Internal Networkを設定してデータベースを完全隔離しておくのも効果的です。

ステップ5:Webサイトの追加とトラッキングタグの設置

Settings > Websitesへ進み、Add websiteをクリックしてサイト名とドメイン(例:myblog.vn)を入力します。すると、Umamiから以下のような埋め込み用スクリプトコードが出力されます:

<script defer src="https://analytics.yourdomain.com/script.js" data-website-id="12345678-abcd-ef01-2345-6789abcdef01"></script>

上記のコードを対象Webサイトの<head>タグ内に貼り付けます。メインサイトがHTTPSで動作している場合のMixed Contentセキュリティエラーを防ぐため、UmamiのサブドメインにはNginxやCaddy(あるいはTraefikによるSSL証明書の自動化)をリバースプロキシとして構成し、Let’s Encryptの無料SSL証明書を適用することをおすすめします。

設置が完了したら、ブラウザのシークレットウィンドウでWebサイトを開き、ページをリロードしてみてください。Umamiの管理画面に戻ると、リアルタイムチャートの数値が即座に反映されるのを確認できるはずです。

4. おわりに

Docker Composeを使ったUmamiのセルフホストにより、わずらわしいCookieバナーの呪縛から解放され、2KBの超軽量スクリプトによってページ表示速度が向上し、アクセスデータを完全に自己管理できるようになります。Webサイトのアクセス解析とあわせてDocker ComposeによるUptime KumaでのWebサイト監視も導入しておけば、サーバーの死活状態もリアルタイムに把握できます。一度セットアップしてしまえば、複雑なメンテナンスを必要とすることなく、長期間安定して稼働し続けてくれます。

Share: