Skip to main content

How to Self-Host Changedetection.io: Website Change Monitoring 2026

·OSSAlt Team
changedetectionmonitoringweb-scrapingself-hostingdocker2026

TL;DR

Changedetection.io (Apache 2.0, ~19K GitHub stars, Python) monitors websites for changes and alerts you when content changes — a free replacement for VisualPing or Distill.io. Use cases: price tracking (Amazon, Best Buy), stock monitoring, government/regulatory pages, job postings, sports schedules, and any site that changes but doesn't have RSS. Supports JavaScript-rendered pages via Playwright/Puppeteer. Distill.io Pro costs $14/month; Changedetection.io is free to self-host.

Key Takeaways

  • Changedetection.io: Apache 2.0, ~19K stars — monitor any website for content changes
  • JavaScript support: Optional Playwright/Puppeteer browser for SPAs and dynamic content
  • CSS/XPath selectors: Monitor specific page elements (not the whole page)
  • Notifications: Email, Slack, Discord, ntfy, Telegram, and 80+ via Apprise
  • Filters: Ignore specific text patterns to reduce false positives
  • Price tracking: Dedicated price change tracking with JSON XPath

Use Cases

Use CaseExample
Price trackingAmazon product → alert when price drops below $X
Stock availability"Add to Cart" button appears → notify
Government updatesNew regulations published
Job postingsNew jobs at target company
Sports schedulesGame dates added or changed
Competitor monitoringNew features or pricing changes
News keywordsAlert when specific terms appear on a page
API monitoringJSON response changes

Part 1: Docker Setup

Basic (No JavaScript)

# docker-compose.yml
services:
  changedetection:
    image: ghcr.io/dgtlmoon/changedetection.io:latest
    container_name: changedetection
    restart: unless-stopped
    ports:
      - "5000:5000"
    volumes:
      - changedetection_data:/datastore
    environment:
      BASE_URL: "https://changes.yourdomain.com"
      HIDE_REFERER: "false"

volumes:
  changedetection_data:

With Playwright Browser (JavaScript Support)

For monitoring SPAs, dynamic pages, and JavaScript-rendered content:

services:
  changedetection:
    image: ghcr.io/dgtlmoon/changedetection.io:latest
    container_name: changedetection
    restart: unless-stopped
    ports:
      - "5000:5000"
    volumes:
      - changedetection_data:/datastore
    environment:
      BASE_URL: "https://changes.yourdomain.com"
      PLAYWRIGHT_DRIVER_URL: ws://sockpuppetbrowser:3000
    depends_on:
      - sockpuppetbrowser

  sockpuppetbrowser:
    image: dgtlmoon/sockpuppetbrowser:latest
    container_name: sockpuppetbrowser
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    environment:
      SCREEN_WIDTH: 1920
      SCREEN_HEIGHT: 1080

volumes:
  changedetection_data:
docker compose up -d

Visit http://your-server:5000 — no login required by default. Add password in settings.


Part 2: HTTPS with Caddy

changes.yourdomain.com {
    reverse_proxy localhost:5000
}

Part 3: Adding Your First Watch

  1. + Add Watch
  2. Paste URL (e.g., https://www.amazon.com/dp/B09R9CTNC5)
  3. Set check interval: 1 hour (default), 15 min, or custom
  4. Save

Changedetection immediately fetches the page and stores a baseline. Next check compares against the baseline — any difference triggers an alert.


Part 4: CSS Selectors (Monitor Specific Elements)

Instead of monitoring the full page (with noisy navigation/ads changes), scope to specific content:

  1. Edit a watch → Visual Filter
  2. Click on the element to monitor (e.g., price, availability text)
  3. Changedetection generates a CSS selector automatically

Or manually set CSS selectors:

/* Monitor only the price: */
#priceblock_dealprice, #priceblock_ourprice, .a-price-whole

/* Monitor availability: */
#availability .a-declarative

/* Monitor a table: */
table.data-table

/* Monitor a specific div: */
div.job-listings-container

Part 5: Price Tracking

Changedetection has dedicated price tracking with threshold alerts:

  1. Add a watch for a product URL
  2. Edit → Filters → Price tracking
  3. Enable Price Change Detection
  4. Set alert threshold: "Alert when price drops below $50"

For JSON APIs:

URL: https://api.example.com/product/123
Filter: json:data.price   # JSONPath to price field

Part 6: Notification Setup

Settings → Notifications → Add Notification

ntfy

URL: ntfy://ntfy.yourdomain.com/changedetection

Slack

URL: slack://your-token@YOUR-WORKSPACE/YOUR-CHANNEL

Discord

URL: discord://webhook-id/webhook-token

Email

URL: smtp://user:password@smtp.yourdomain.com:587?to=you@yourdomain.com&from=cd@yourdomain.com

Changedetection uses Apprise — any Apprise-compatible notification URL works.

Per-Watch Notifications

Each watch can have its own notification settings:

  1. Edit watch → Notifications tab
  2. Override global settings
  3. Useful for routing: "Price changes → SMS, government pages → email"

Part 7: Filters and Ignore Rules

Reduce false positives from dynamic content (ads, timestamps, visitor counts):

Edit watch → Filters & Triggers:

# Ignore lines containing these strings (regex supported):
visitor counter
last updated
Advertisement

# Trigger only when page contains this text:
Trigger text contains: "In Stock"

# Trigger only when text is removed:
Trigger text removed: "Out of Stock"

Ignore regions (visual selector):

  1. Edit watch → Visual Filter
  2. Toggle to "Ignore" mode
  3. Click regions to exclude (e.g., the ad sidebar)

Part 8: Browser Steps (Login-Protected Pages)

Monitor pages that require login using Playwright:

  1. Edit watch → Browser Steps
  2. Add steps:
    • Navigate to https://example.com/login
    • Fill input[name=email] with you@example.com
    • Fill input[name=password] with your-password
    • Click button[type=submit]
    • Wait for element .dashboard
  3. Save — Changedetection now logs in before checking

Part 9: Tags and Groups

Organize watches with tags:

Tags: amazon-prices, job-boards, government

Filter dashboard by tag. Bulk-apply notification settings to a tag group.


Part 10: API

# List all watches:
curl https://changes.yourdomain.com/api/v1/watch \
  -H "x-api-key: your-api-key"

# Add a watch:
curl -X POST https://changes.yourdomain.com/api/v1/watch \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","tag":"monitoring","title":"Example Site"}'

# Get change history:
curl "https://changes.yourdomain.com/api/v1/watch/UUID/history" \
  -H "x-api-key: your-api-key"

# Generate API key: Settings → API Access Token

Maintenance

# Update:
docker compose pull
docker compose up -d

# Logs:
docker compose logs -f changedetection

# Backup:
tar -czf changedetection-backup-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect changedetection_changedetection_data --format '{{.Mountpoint}}')

# Purge old history (saves disk space):
# Settings → Data → Purge old history

See all open source monitoring and automation tools at OSSAlt.com/categories/monitoring.

Comments