問題:気づかないうちに大事なことが起きている
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
changedetectionとplaywright-chromeの両方がrunning状態になっているはずだ。ブラウザでhttp://<your-homelab-ip>:5000を開いてみよう。
最初の監視を追加する
メインダッシュボードの入力フィールドにURLを貼り付けてWatchをクリックする。Changedetection.ioはすぐにページを取得してベースラインのスナップショットを保存する。以降のチェック(デフォルト間隔:24時間、監視ごとに調整可能)では、このベースラインとの差分を比較する。
特定の監視の間隔を変更するには、監視名をクリック → Edit → Time between checksフィールドを設定する。価格や在庫ページなら、30分〜2時間程度が現実的な範囲だ――変更を確実に捉えられる頻度でありながら、対象サーバーに過負荷をかけない程度に抑えられる。
Telegram通知の設定
Telegramボットの作成
- Telegramを開き、@BotFatherを検索する。
/newbotを送信してプロンプトに従い、発行されたHTTP APIトークンをコピーする。- 新しいボットにメッセージを送ってチャットを初期化する。
- 以下のコマンドをターミナルで実行してチャット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 & TriggersのCSS/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、いずれも使える)を前段に置くこと。次に、インスタンスが自宅ネットワーク外からアクセスできる場合は、基本認証を追加すること。どちらも難しい作業ではなく、センシティブな内容の監視を始める前に対応しておく価値がある。

