Stop Being a Slave to the F5 Key
My monitoring system currently manages 15 servers via Prometheus and Grafana. However, there are things these infrastructure tools cannot reach: the content inside a third-party website.
Have you ever spent a whole week just camping for a sale item or waiting for a job announcement from your dream company? Instead of wasting 30 minutes every morning scrolling through 10 browser tabs, I chose to let a bot handle the automated endpoint and website monitoring. Previously, I missed an important security update for an open-source library just because they didn’t have a mailing list. That’s when I realized that manual monitoring is both exhausting and error-prone.
Why Do Zabbix or Uptime Kuma Fall Short?
System monitoring tools usually only care about technical metrics like CPU or RAM, which is quite different from Real User Monitoring (RUM). When we need to monitor displayed content, we hit three major hurdles:
- Dynamic Content: Websites using React or Vue will return empty JavaScript code if you just use a simple
curl. - Anti-Bot Mechanisms: If you request continuously with the same pattern, your IP will be “executed” by Cloudflare in a heartbeat.
- UI Changes: A self-written Python script can suddenly die just because the web admin renamed a CSS
class.
What is the Best Solution Today?
Typically, you have three main options to solve this problem:
- Write Python scripts (BeautifulSoup/Selenium): Flexible but extremely high maintenance for code and cronjob management.
- Use SaaS services (VisualPing, Distill.io): Fast and beautiful. However, the cost is very high if you want to check 50 pages with a frequency of every 5 minutes.
- Self-hosted: This is my number one choice. You have full control over your data, no limit on the number of pages, and it’s completely free.
After testing many tools, I settled on changedetection.io. It supports Playwright to handle heavy JS and integrates dozens of notification channels via Apprise.
Deploy with Docker Compose in 5 Minutes
Using Docker helps isolate the environment and makes upgrades extremely fast. I will use an additional playwright-chrome container to handle modern websites.
1. Set up the docker-compose.yml file
Create a new directory and paste the following content into the configuration file. Note the shm_size part to prevent Chrome from crashing when rendering heavy pages.
version: '3.2'
services:
changedetection:
image: dgtlmoon/changedetection.io
container_name: changedetection
volumes:
- ./data:/datastore
ports:
- 5000:5000
environment:
- BASE_URL=http://localhost:5000
- PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000/?stealth=1
restart: unless-stopped
playwright-chrome:
image: browserless/chrome:latest
restart: unless-stopped
shm_size: '2gb'
environment:
- MAX_CONCURRENT_SESSIONS=10
Pro tip: The ?stealth=1 parameter above is extremely valuable. It helps the browser simulate real user behavior to bypass basic bot filters.
2. Launch the system
Type a single command to activate:
docker-compose up -d
Now, open your browser and access http://Server-IP:5000.
Optimizing Monitoring and Notifications
Don’t monitor the entire website because you will receive notification spam. Use CSS Selector to target important data areas.
Example: To track the price of a laptop on an e-commerce site, press F12, find the tag containing the price. Copy that selector (e.g., .product-price-current) and paste it into the Filters > CSS Filter Selector section in the tool.
Receive Notifications via Telegram
Go to Settings > Notifications, fill in the URL according to the Apprise syntax. For Telegram, the format will be:
tgram://bot_token/chat_id/
Use the {{diff}} variable in the message content to know exactly how much the price just dropped or what content was newly added.
Real-world Experience: Avoiding False Alarms
I was once constantly spammed by Telegram because a website had a widget displaying “Number of people online,” highlighting the need for better SRE efficiency. Every time it scanned, this number jumped, making the tool think the content had changed.
The solution is to use the Ignore Text feature, a standard practice for reducing alert noise. Enter frequently changing phrases here, for example: /\d+ views/ or /Updated at:.*/. Additionally, for strict sites, set the Time Between Checks to about 1 hour to avoid IP blocking.
Conclusion
Automating website monitoring frees up my hands to do more important things. From hunting tech deals to tracking new CVEs, everything runs 24/7 on a low-spec VPS. If you have trouble writing CSS Selectors, leave a comment below!

