Changedetection.ioをDockerでインストール:ウェブサイトの変更を監視してTelegramにリアルタイム通知を届ける【HomeLab構築ガイド】

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

問題:気づかないうちに大事なことが起きている

2週間毎日、商品ページをブラウザで手動チェックし続けたのに、寝ている間に在庫が復活して売り切れてしまった――そんな経験をしたことはないだろうか。競合他社の料金ページ、行政の申請フォーム、求人情報。いつの間にか、手動での監視は単なる作業を超えて、もう一つの仕事になっている。

原因は怠慢ではない。ウェブサイトはコンテンツが変わっても通知してくれないのだ。RSSフィードは半ば廃れている。メールニュースレターはマーケティング目的でキュレーションされており、特定のページ内容を追跡するためには使えない。ブラウザ拡張機能はこの用途に向いているものもあるが、動作が不安定で、特定のマシンに依存し、プライバシー面でも不安が残る。

本当に必要なのは、HomeLabで24時間365日稼働する自己ホスト型のサービスだ。スケジュールに従ってURLをチェックし、コンテンツの差分を取り、普段から目を向けている場所へアラートを送ってくれるもの。それがまさにChangedetection.ioであり、Dockerで動かすのに10分もあれば十分だ。

Changedetection.ioでできること

Changedetection.ioはオープンソースのウェブコンテンツ監視ツールだ。設定した間隔でページを取得し、前回の内容と比較して、差分が検出されると通知を発火させる。

単純なブラウザ拡張機能より優れている点は以下のとおりだ:

  • ブラウザベースのレンダリング対応 — Playwrightを介して、通常のHTTPフェッチでは空白しか返さないJavaScript重視のSPAにも対応できる。
  • XPath/CSSセレクタによるフィルタリング — 常に変化するナビゲーションバーやフッターを無視して、ページの特定セクションだけを監視対象に絞れる。
  • 通知連携 — Telegram、Slack、Discord、メール、ntfy、Pushoverなど、裏側でAppriseを使いながら多数のサービスへ通知できる。
  • 変更履歴 — 検出された変更はすべてdiffビュー付きで保存され、何がどう変わったかを正確に確認できる。
  • ビジュアルdiff — Web UIで追加・削除されたテキストをハイライト表示する。

Docker Composeで動かすことで、常時稼働の監視環境が手に入る。ブラウザタブを開きっぱなしにする必要はもうない。

Docker ComposeでChangedetection.ioをセットアップする

前提条件

HomeLabホストにDockerとDocker Composeがインストールされている必要がある。Ubuntu/Debianの場合:

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

動作確認:

docker compose version

プロジェクトディレクトリの作成

mkdir -p ~/homelab/changedetection/datastore
cd ~/homelab/changedetection

Docker Composeファイルの作成

以下の内容でdocker-compose.ymlを作成する。この構成にはJavaScriptレンダリング済みページ向けのPlaywrightブラウザコンテナが含まれている。静的サイトのみを監視する場合は、playwright-chromeサービスとPLAYWRIGHT_DRIVER_URL環境変数を削除すれば、メモリを300〜500MB程度節約できる。

services:
  changedetection:
    image: ghcr.io/dgtlmoon/changedetection.io
    container_name: changedetection
    hostname: changedetection
    volumes:
      - ./datastore:/datastore
    environment:
      - PORT=5000
      - PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000
    ports:
      - "5000:5000"
    depends_on:
      playwright-chrome:
        condition: service_started
    restart: unless-stopped

  playwright-chrome:
    image: dgtlmoon/sockpuppetbrowser:latest
    container_name: playwright-chrome
    hostname: playwright-chrome
    cap_add:
      - SYS_ADMIN
    restart: unless-stopped
    environment:
      - SCREEN_WIDTH=1920
      - SCREEN_HEIGHT=1024
      - SCREEN_DEPTH=16
      - MAX_CONCURRENT_CHROME_PROCESSES=10

サービスの起動

docker compose up -d

両方のコンテナが起動していることを確認する:

docker compose ps

changedetectionplaywright-chromeの両方がrunning状態になっているはずだ。ブラウザでhttp://<your-homelab-ip>:5000を開いてみよう。

最初の監視を追加する

メインダッシュボードの入力フィールドにURLを貼り付けてWatchをクリックする。Changedetection.ioはすぐにページを取得してベースラインのスナップショットを保存する。以降のチェック(デフォルト間隔:24時間、監視ごとに調整可能)では、このベースラインとの差分を比較する。

特定の監視の間隔を変更するには、監視名をクリック → EditTime between checksフィールドを設定する。価格や在庫ページなら、30分〜2時間程度が現実的な範囲だ――変更を確実に捉えられる頻度でありながら、対象サーバーに過負荷をかけない程度に抑えられる。

Telegram通知の設定

Telegramボットの作成

  1. Telegramを開き、@BotFatherを検索する。
  2. /newbotを送信してプロンプトに従い、発行されたHTTP APIトークンをコピーする。
  3. 新しいボットにメッセージを送ってチャットを初期化する。
  4. 以下のコマンドをターミナルで実行してチャットIDを取得する(TOKENは実際のボットトークンに置き換えること):
curl -s "https://api.telegram.org/botTOKEN/getUpdates" | python3 -m json.tool

レスポンスの中から"chat":{"id": 123456789}を探す。この数字がチャットIDだ。

Changedetection.ioに通知URLを追加する

Changedetection.ioは通知にAppriseを使用している。Telegram用のフォーマットは以下のとおりだ:

tgram://BOT_TOKEN/CHAT_ID

Web UIのSettings → Notificationsに移動してAppriseのURLを貼り付け、Send test notificationをクリックする。数秒以内にTelegramへテストメッセージが届くはずだ。

監視ごとにEdit → Notificationsから通知URLを個別に設定することもできる。特定の監視はグループチャットに、他の監視は個人DMへ送りたい場合などに便利だ。

通知メッセージのカスタマイズ

デフォルトのメッセージテンプレートはそのまま使っても問題ない。変更したい場合はSettings → Notifications → Notification bodyへ移動する。よく使われる変数は以下のとおりだ:

  • {{watch_url}} — 監視対象のURL
  • {{watch_title}} — 監視に付けたラベル
  • {{diff}} — 変更内容のテキストdiff
  • {{preview_url}} — Changedetectionインスタンスのdiffビューへのリンク

Telegram向けに使いやすいテンプレート:

🔔 Change detected: {{watch_title}}

URL: {{watch_url}}

Preview: {{preview_url}}

実践:JavaScriptレンダリングページの監視

ReactやVueで構築されたアプリのように、最初のHTMLレスポンスの後にブラウザ側でコンテンツを読み込むページがある。通常のHTTPフェッチでは空のシェルしか返ってこない。ここでPlaywrightコンテナが真価を発揮する。

監視の追加・編集時にRequest → Fetch backendまでスクロールし、Basic fast FetchからChrome/Javascriptへ切り替える。Changedetection.ioはその監視をPlaywrightブラウザ経由でルーティングし、スナップショットを取る前にページを完全にレンダリングする。

さらにFilters & TriggersCSS/XPathフィルタを組み合わせると、商品価格など気になる要素だけを監視できる:

css:.product-price

こうすることで、ページ上の他の要素はすべて無視される。広告がローテーションされたり、クッキーバナーが更新されても通知は来ない。価格そのものが変わったときだけ通知が届く。

データを安全に保管する

すべての監視設定と変更履歴はホスト上の./datastoreに保存される。バックアップはコマンド一つで完了する:

tar -czf changedetection-backup-$(date +%Y%m%d).tar.gz ./datastore

別のホストへの移行も同様に簡単だ――datastoreディレクトリをコピーしてコンテナを起動すれば、監視設定、履歴、通知設定がすべてそのまま再現される。

私自身、いくつかのベンダーの価格ページや社内ダッシュボードの監視にこの構成を使っているが、非常に安定している。Playwrightコンテナは同時チェック数によって512MB〜1GB程度のメモリを使うが、4GB以上のRAMを積んだHomeLabマシンであれば問題にならないだろう。

次のステップ

ここまでで、スケジュールに従ってURLをチェックし、JavaScriptレンダリングに対応し、監視対象のコンテンツだけに変更範囲を絞り、何か変化があった瞬間にTelegramへアラートを送る自己ホスト型の監視環境が完成した。開きっぱなしのブラウザタブも、見逃した在庫復活も、もう過去の話だ。

次に取り組むべきことは二つある。まず、ポート5000を直接公開せずにHTTPSでUIへアクセスできるよう、リバースプロキシ(Nginx Proxy Manager、Caddy、Traefik、いずれも使える)を前段に置くこと。次に、インスタンスが自宅ネットワーク外からアクセスできる場合は、基本認証を追加すること。どちらも難しい作業ではなく、センシティブな内容の監視を始める前に対応しておく価値がある。

Share: