changedetection.io¶
Self-Hosted Website Change Detection
changedetection.io is a self-hosted website change detection and monitoring tool. It watches web pages for content changes and sends notifications, with support for JavaScript-rendered pages via Playwright+Chrome.
Why Choose changedetection.io¶
- Privacy first - monitored URLs and change history stay on your own server
- JavaScript support - fetch pages rendered with JavaScript via Playwright+Chrome
- Flexible notifications - supports many notification backends (email, Slack, Telegram, etc.)
- Visual selector - pick exactly which part of a page to monitor
- Filters and triggers - ignore noise with CSS/XPath selectors, text filters, and trigger conditions
Install¶
Infrastructure Configuration¶
Infrastructure as Code
The canonical configuration is maintained at Benoit/OpenTofu.
The changedetection.io VM is provisioned with OpenTofu. Two extra block volumes are attached: one for Docker data and one for /opt where changedetection.io lives.
resource "incus_storage_volume" "changedetection_var_lib_docker" {
name = "changedetection_var_lib_docker"
pool = incus_storage_pool.default.name
content_type = "block"
config = {
"size" = "50GiB"
}
}
resource "incus_storage_volume" "changedetection_opt" {
name = "changedetection_opt"
pool = incus_storage_pool.default.name
content_type = "block"
config = {
"size" = "10GiB"
}
}
resource "incus_instance" "changedetection" {
name = "changedetection"
image = "images:ubuntu/24.04"
type = "virtual-machine"
config = {
"limits.cpu" = 2
"limits.memory" = "4GiB"
}
device {
name = "root"
type = "disk"
properties = {
size = "25GiB"
path = "/"
pool = incus_storage_pool.default.name
}
}
device {
name = "var_lib_docker"
type = "disk"
properties = {
# Mount manually inside the VM: path = "/var/lib/docker"
source = incus_storage_volume.changedetection_var_lib_docker.name
pool = incus_storage_pool.default.name
}
}
device {
name = "opt"
type = "disk"
properties = {
# Mount manually inside the VM: path = "/opt"
source = incus_storage_volume.changedetection_opt.name
pool = incus_storage_pool.default.name
}
}
}
Manual mount required
The var_lib_docker and opt block volumes are attached to the VM but not auto-mounted. After the VM first boots, format and mount them manually before installing Docker or cloning changedetection.io.
Deploy Infrastructure¶
Inside the VM: Format and Mount Volumes¶
After the first boot, identify the two attached block devices and set them up:
Format and mount the volumes
Persist mounts across reboots
Inside the VM: Docker and changedetection.io¶
Clone the changedetection.io repository
Enable Playwright+Chrome
Edit docker-compose.yml to uncomment the Playwright browser service and its dependency:
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io
container_name: changedetection
hostname: changedetection
volumes:
- changedetection-data:/datastore
environment:
- PLAYWRIGHT_DRIVER_URL=ws://browser-sockpuppet-chrome:3000
ports:
- 0.0.0.0:5000:5000
- "[::]:5000:5000"
restart: unless-stopped
depends_on:
browser-sockpuppet-chrome:
condition: service_started
browser-sockpuppet-chrome:
hostname: browser-sockpuppet-chrome
image: dgtlmoon/sockpuppetbrowser:latest
cap_add:
- SYS_ADMIN
restart: unless-stopped
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1024
- SCREEN_DEPTH=16
- MAX_CONCURRENT_CHROME_PROCESSES=10
volumes:
changedetection-data:
Related Documentation:
- Infrastructure Overview - Complete self-hosting architecture