← Back to changedetection.io

How to Deploy & Use changedetection.io

changedetection.io Deployment and Usage Guide

1. Prerequisites

Runtime Requirements:

  • Python 3.8 or higher
  • Node.js (for optional Playwright support)
  • Modern web browser for accessing the web interface

Database/Storage:

  • Local filesystem access for datastore (default: /datastore)
  • Optional: External database for scaling (though current implementation uses JSON files)

Optional Dependencies:

  • Docker and Docker Compose (recommended for production)
  • Playwright for advanced browser automation features
  • Redis for queue management (if scaling beyond single instance)

Accounts/Services (Optional):

  • Notification service accounts (Discord, Slack, Telegram, Email SMTP, etc.)
  • Proxy service accounts if monitoring rate-limited sites

2. Installation

Option A: Docker (Recommended)

# Create a directory for persistent storage
mkdir datastore

# Run with Docker
docker run -d \
  --name changedetection \
  -p 5000:5000 \
  -v $(pwd)/datastore:/datastore \
  dgtlmoon/changedetection.io

Option B: Docker Compose

version: '3'
services:
  changedetection:
    image: dgtlmoon/changedetection.io
    ports:
      - "5000:5000"
    volumes:
      - ./datastore:/datastore
    environment:
      - PLAYWRIGHT_DRIVER_URL=ws://playwright:3000
      - BASE_URL=http://localhost:5000
    depends_on:
      - playwright
  
  playwright:
    image: browserless/chrome:latest
    ports:
      - "3000:3000"
docker-compose up -d

Option C: Python Source Installation

# Clone the repository
git clone https://github.com/dgtlmoon/changedetection.io.git
cd changedetection.io

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Install Playwright browsers (optional)
playwright install chromium

# Install Node.js dependencies for frontend (if needed)
npm install  # or yarn install

3. Configuration

Environment Variables

Core Settings:

# Base URL for notification links (required for proper notifications)
BASE_URL=http://your-server.com:5000

# Datastore location
DATASTORE_PATH=/datastore

# Minimum recheck time (seconds)
MINIMUM_SECONDS_RECHECK_TIME=3

# Playwright integration
PLAYWRIGHT_DRIVER_URL=ws://localhost:3000
PLAYWRIGHT_TIMEOUT=30000

# Security
SECRET_KEY=your-secret-key-here
BLOCK_SIMPLEHOSTS=False  # Set to True to block localhost/private IP monitoring

Notification Configuration:

# Email notifications
NOTIFICATION_URLS=smtp://user:pass@smtp.server:587/?to=recipient@example.com

# Webhook notifications
NOTIFICATION_URLS=https://discord.com/api/webhooks/your-webhook-url
NOTIFICATION_URLS=https://hooks.slack.com/services/your-webhook-url

# Multiple notifications (comma separated)
NOTIFICATION_URLS=mailto:admin@example.com,https://webhook.url

Performance Tuning:

# Worker settings
WORKER_MAX_JOBS=10
WORKER_MAX_RUNTIME=3600

# Snapshot compression
SNAPSHOT_BROTLI_COMPRESSION_THRESHOLD=20480  # 20KB threshold

# Request settings
HTTP_PROXY=http://your-proxy:8080
HTTPS_PROXY=http://your-proxy:8080
NO_PROXY=localhost,127.0.0.1

Configuration Files

The application stores configuration in JSON files within the datastore:

  • changedetection.json - Global settings
  • {watch_uuid}/watch.json - Individual watch configurations
  • {tag_uuid}/tag.json - Tag configurations

Watch Configuration Examples

Basic Watch:

{
  "url": "https://example.com/product",
  "tag": "monitoring",
  "time_between_check": {"minutes": 30},
  "fetch_backend": "system"
}

Advanced Watch with Filters:

{
  "url": "https://api.example.com/data",
  "method": "GET",
  "ignore_text": ["ADVERTISEMENT", "Sponsored"],
  "css_filter": ".product-price",
  "notification_urls": ["https://discord.com/api/webhooks/..."],
  "restock": {
    "track": true,
    "notification_body": "Price changed to {{price}}"
  }
}

4. Build & Run

Development Mode

# From source directory
python changedetection.py

# Or using Flask directly
export FLASK_APP=changedetection.py
export FLASK_ENV=development
flask run --host=0.0.0.0 --port=5000

Production Mode

# Using Gunicorn (recommended for production)
pip install gunicorn
gunicorn --bind 0.0.0.0:5000 --workers 4 changedetection:app

# With environment variables
DATASTORE_PATH=/datastore \
BASE_URL=https://your-domain.com \
gunicorn --bind 0.0.0.0:5000 changedetection:app

Building Docker Image

# Build from source
docker build -t changedetection-custom .

# Run custom build
docker run -d \
  -p 5000:5000 \
  -v /path/to/datastore:/datastore \
  changedetection-custom

5. Deployment

Platform Recommendations

1. Docker-based Platforms:

  • Docker Swarm/Kubernetes: For high availability
  • Portainer: Easy Docker management
  • Cloud Run/ECS/Fargate: Managed container services

2. Traditional VPS:

  • Ubuntu/Debian with systemd:
# Create systemd service file: /etc/systemd/system/changedetection.service
[Unit]
Description=changedetection.io
After=network.target

[Service]
Type=simple
User=changedetection
WorkingDirectory=/opt/changedetection.io
Environment="DATASTORE_PATH=/var/lib/changedetection"
Environment="BASE_URL=https://your-domain.com"
ExecStart=/opt/changedetection.io/venv/bin/gunicorn --bind 0.0.0.0:5000 changedetection:app
Restart=always

[Install]
WantedBy=multi-user.target

3. Reverse Proxy Setup (Nginx):

server {
    listen 80;
    server_name changedetection.your-domain.com;
    
    location / {
        proxy_pass http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

4. Cloud Platforms:

  • Railway.app: One-click deployment with persistent storage
  • Fly.io: Global edge deployment
  • Hetzner/OVH: Affordable VPS with good storage options

Scaling Considerations

Single Instance:

  • Suitable for up to 1000 watches
  • Uses in-memory queue system
  • File-based JSON storage

Multi-Instance:

  • Requires external queue (Redis)
  • Shared filesystem or database for datastore
  • Load balancer with sticky sessions
# Example with Redis queue
docker run -d \
  --name changedetection \
  -e REDIS_URL=redis://redis-server:6379 \
  -e DATASTORE_PATH=/datastore \
  -v shared-storage:/datastore \
  dgtlmoon/changedetection.io

6. Troubleshooting

Common Issues

1. "Base URL not set" in notifications:

# Set the BASE_URL environment variable
export BASE_URL=https://your-actual-domain.com
# Or in Docker:
docker run -e BASE_URL=https://your-domain.com ...

2. Playwright not working:

# Ensure Playwright service is running
docker run -d -p 3000:3000 browserless/chrome:latest

# Set the connection URL
export PLAYWRIGHT_DRIVER_URL=ws://localhost:3000

3. Watch not detecting changes:

  • Check if page requires JavaScript (enable Playwright)
  • Verify CSS/XPATH filters are correct
  • Check for anti-bot protections (may need proxies)
  • Enable "Treat text as text" for JSON/API responses

4. High memory usage:

# Reduce snapshot retention
export SNAPSHOT_BROTLI_COMPRESSION_THRESHOLD=10240
# Limit number of snapshots per watch in settings
# Increase check intervals for less frequent monitoring

5. Database/schema migration issues:

# The application includes automatic schema migrations
# Check logs for update messages
# Backups are automatically created in /datastore as .tar.gz files
# To restore: tar -xzf before-update-{N}-{timestamp}.tar.gz -C /datastore

6. Permission errors (Docker):

# Set proper permissions on host directory
chown -R 1000:1000 /path/to/datastore
# Or use named volumes
docker volume create changedetection-data

7. Notifications not sending:

  • Verify notification URLs are correct
  • Check SMTP credentials for email
  • Test webhook URLs with curl
  • Check application logs for notification errors

Logging and Debugging

# Enable verbose logging
export LOG_LEVEL=DEBUG

# Check application logs
docker logs changedetection

# Monitor specific watch
# In UI: Watch → History → View processing details

# Test fetch manually
curl -X POST http://localhost:5000/api/v1/watch/{uuid}/check

Performance Optimization

For large deployments (>500 watches):

# Increase worker count
export WORKER_COUNT=4

# Use external Redis for queue
export REDIS_URL=redis://localhost:6379

# Adjust check intervals
# Use global default settings for consistency
# Consider dedicated instance for Playwright-heavy watches

Storage optimization:

  • Enable Brotli compression (default for snapshots >20KB)
  • Regularly prune old snapshots via settings
  • Consider mounting /datastore on SSD storage