DevOps и Docker 12 мин чтения 2026-10-07

Мониторинг изменений веб-страниц и цен в ChangeDetection.io: развертывание в Docker Compose с рендерингом JavaScript и алертами в Telegram

Пошаговое руководство по установке self-hosted платформы ChangeDetection.io в связке с Playwright на VDS: отслеживание динамических сайтов, фильтрация CSS/XPath, мониторинг цен и моментальные оповещения в Telegram.

Алексей Иванов Проверено инженерами SysKit.ru

Любой вебмастер, системный администратор или аналитик регулярно сталкивается с необходимостью отслеживать изменения в сети: проверить, не изменилась ли цена у поставщика, не изменился ли статус доступности товара, не выкатили ли обновление документации API без RSS-рассылки, или не подвергся ли рабочий сайт тихому дефейсу или сбою верстки. Популярные облачные SaaS-сервисы выставляют жесткие лимиты: у Distill минимальный персональный тариф начинается от 15$/мес за ограниченное число проверок, а коммерческие планы Visualping стартуют от 50$/мес за мониторинг динамических страниц с JavaScript.

Открытая платформа ChangeDetection.io решает эту проблему раз и навсегда. Развернув ее на собственном VDS-сервере в связке с безголовым браузером Chromium (Playwright), вы получаете мощную автономную систему веб-мониторинга неограниченного числа страниц с поддержкой интерактивного выбора элементов, фильтрации по CSS/XPath, обхода базовой защиты и мгновенными оповещениями в Telegram.

Зачем нужен ChangeDetection.io и какие задачи он решает

В отличие от классических утилит проверки доступности вроде Uptime Kuma или нашего собственного Telegram-бота SysKit Uptime, которые проверяют статус-код HTTP (200 OK) и отклик сервера, ChangeDetection.io анализирует непосредственно содержимое веб-документа, его DOM-структуру и визуальное отображение.

Ключевые сценарии практического применения платформы:

  • Контроль целостности и безопасности сайтов (Anti-Defacement): Мониторинг ключевых страниц вашего проекта. Если злоумышленник внесет скрытые правки в скрипты, вставит сторонние ссылки или упадет блок критической информации, система моментально зафиксирует расхождение в тексте или DOM-дереве.
  • Отслеживание цен и динамики наличия товаров: Парсинг интернет-магазинов, маркетплейсов и поставщиков. ChangeDetection.io умеет извлекать числовые значения цен, строить графики их колебаний и присылать оповещение только при снижении стоимости ниже заданной планки.
  • Мониторинг обновлений без RSS: Отслеживание релизов в репозиториях, новостей регулирующих органов, изменений в пользовательских соглашениях (ToS), появление записей в реестрах или списков вакансий.
  • Проверка сетевых параметров и сервисов: Контроль доступности портов через наш онлайн-чекер портов, валидация SSL-сертификатов и отслеживание изменений DNS-записей доменов.

Экономическая выгода: Стоимость содержания собственного инстанса ChangeDetection.io равна стоимости недорогого VDS (от 200–350 руб/мес), при этом вы не ограничены лимитами на количество ссылок, частоту опроса или размер сохраняемой истории версий.

Архитектура: встроенный парсер vs браузерный движок Playwright

Главная сложность при веб-скрейпинге современных сайтов — повсеместное использование Single Page Applications (SPA на React, Vue, Angular, Next.js), ленивой подгрузки контента (Lazy Loading) и защиты от базовых роботов. В ChangeDetection.io реализована гибкая двухуровневая архитектура сбора данных:

  1. Встроенный HTTP-парсер (Basic Requests): Легковесный клиент на базе Python urllib3/requests. Работает с околонулевым расходом оперативной памяти (не более 1–2 МБ на запрос) и отдачей за доли секунды. Идеален для классических статических страниц, блогов на WordPress, XML-фидов и JSON API. Однако он бессилен, если контент генерируется клиентским JavaScript.
  2. Браузерный движок Playwright (sockpuppetbrowser): Специализированный микросервис от автора ChangeDetection.io. Он запускает полноценный headless-браузер Chromium, загружает страницу со всеми скриптами, эмулирует реальный экран монитора (1920x1080) и возвращает в основной сервис полностью отрисованный DOM-скриншот и отрендеренный HTML-код.

Связь между ядром ChangeDetection.io и браузером осуществляется по протоколу WebSocket через переменную окружения PLAYWRIGHT_DRIVER_URL=ws://browser-sockpuppet-chrome:3000. Это позволяет изолировать нестабильный процесс браузера в отдельном изолированном контейнере и жестко ограничить его потребление системных ресурсов.

Развертывание ChangeDetection.io в Docker Compose с лимитами ресурсов

Для надежного развертывания создадим рабочую директорию на сервере под управлением Ubuntu или Debian. Вспомогательный контейнер sockpuppetbrowser оптимизирован для безопасного рендеринга и по умолчанию запускает Chromium с изоляцией сессий. Временные профили браузера выносятся в оперативную память через tmpfs: - /tmp, что ускоряет обработку и исключает износ NVMe-диска сервера.

Создайте рабочую директорию и перейдите в нее:

sudo mkdir -p /opt/changedetection/datastore
cd /opt/changedetection

Создайте файл docker-compose.yml со следующей проверенной боевой конфигурацией. Обратите внимание, что веб-порт 5000 привязан строго к локальному интерфейсу 127.0.0.1, чтобы предотвратить нежелательный обход системного фаервола UFW:

services:
  changedetection:
    # Фиксируем стабильный релиз вместо плавающего тега latest
    image: ghcr.io/dgtlmoon/changedetection.io:0.60.8
    container_name: changedetection
    restart: unless-stopped
    volumes:
      - ./datastore:/datastore
    environment:
      # Подключение внешнего Playwright рендерера по WebSocket
      - PLAYWRIGHT_DRIVER_URL=ws://browser-sockpuppet-chrome:3000
      # Базовый публичный URL вашего домена
      - BASE_URL=https://track.example.com
      # Безопасно только при привязке к 127.0.0.1: доверяет заголовкам X-Forwarded-* от Nginx
      - USE_X_SETTINGS=1
      # Сокрытие заголовка Referer при мониторинге целевых ресурсов
      - HIDE_REFERER=true
      # Согласованное число параллельных воркеров опроса
      - FETCH_WORKERS=4
      # Часовой пояс для корректного отображения времени проверок
      - TZ=Europe/Moscow
    ports:
      # Безопасная привязка: только локальный хост, без открытия 0.0.0.0
      - "127.0.0.1:5000:5000"
    depends_on:
      - browser-sockpuppet-chrome
    mem_limit: 512m
    cpus: 1.0

  browser-sockpuppet-chrome:
    # Стабильная версия браузерного движка
    image: dgtlmoon/sockpuppetbrowser:0.60.8
    container_name: changedetection-chrome
    restart: unless-stopped
    # Для production с высокими требованиями безопасности используйте seccomp-профиль chrome.json
    cap_add:
      - SYS_ADMIN
    environment:
      - SCREEN_WIDTH=1920
      - SCREEN_HEIGHT=1080
      # Лимит одновременных процессов браузера (остальные запросы ставятся в очередь до 120 с)
      - MAX_CONCURRENT_CHROME_PROCESSES=4
    # Хранение временных сессий браузера в оперативной памяти (быстрее и без износа диска)
    tmpfs:
      - /tmp
    mem_limit: 1536m
    cpus: 1.5

Безопасность сетевых портов: Директива 127.0.0.1:5000:5000 гарантирует, что панель управления недоступна напрямую по открытому IP-адресу сервера из глобальной сети. Любой внешний трафик должен проходить через обратный прокси-сервер с обязательным шифрованием SSL/TLS.

Запустите созданный стек контейнеров в фоновом режиме:

sudo docker compose up -d

Проверьте, что оба контейнера успешно запустились и перешли в рабочий статус Up:

sudo docker compose ps
sudo docker compose logs -f changedetection

Для создания регулярных резервных копий базы и снимков страниц достаточно сохранять каталог данных:

sudo tar -czf /opt/changedetection-backup-$(date +%F).tar.gz -C /opt/changedetection datastore

Обновление сервисов до последних стабильных релизов выполняется стандартными командами:

# 1. Обязательный бэкап данных перед обновлением (миграции БД могут быть необратимы)
sudo tar -czf /opt/changedetection-preupdate-$(date +%F).tar.gz -C /opt/changedetection datastore

# 2. Скачивание новых образов и перезапуск
sudo docker compose pull && sudo docker compose up -d

Настройка безопасного веб-доступа через Nginx и Caddy с HTTPS

Так как контейнер слушает локальный сокет 127.0.0.1:5000, для удобного доступа через доменное имя (например, track.example.com) и шифрования трафика по HTTPS необходимо настроить фронтенд веб-сервер. Вы можете выбрать классический Nginx либо современный Caddy 2 с автоматическим выпуском сертификатов.

Предварительно создайте в DNS-панели вашего домена запись типа A с именем track, указывающую на публичный IP-адрес вашего VDS.

Вариант 1: Классический Nginx с Certbot

Если на вашем сервере уже используется Nginx (или вы можете быстро сгенерировать оптимальную конфигурацию через наш генератор конфигов Nginx), создайте файл виртуального хоста /etc/nginx/sites-available/changedetection.conf:

# Защита от брутфорса авторизации (добавьте директиву в блок http в /etc/nginx/nginx.conf)
# limit_req_zone $binary_remote_addr zone=changedetection_limit:10m rate=10r/s;

server {
    listen 80;
    server_name track.example.com;

    client_max_body_size 50M;

    # Конфигурация рассчитана на Nginx, установленный на хосте VDS.
    # Если Nginx работает внутри соседнего Docker-контейнера, используйте общее имя сети или host.docker.internal
    location / {
        # Ограничение допустимых HTTP-методов
        limit_except GET POST HEAD OPTIONS {
            deny all;
        }

        proxy_pass http://127.0.0.1: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;

        # Поддержка WebSocket для интерактивного визуального селектора
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Увеличенные таймауты для тяжелых страниц с долгим рендерингом
        proxy_read_timeout 120s;
        proxy_send_timeout 120s;
    }
}

Активируйте конфигурацию и примените изменения:

sudo ln -s /etc/nginx/sites-available/changedetection.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Выпустите бесплатный доверенный SSL-сертификат Let's Encrypt с автоматической переадресацией HTTP на HTTPS:

sudo certbot --nginx -d track.example.com --non-interactive --agree-tos -m admin@example.com --redirect

После выпуска сертификата убедитесь в корректности цепочки шифрования через наш онлайн SSL-чекер SysKit.

Вариант 2: Автоматический HTTPS в Caddy 2

Если вы предпочитаете максимальную простоту без ручной возни с Certbot, веб-сервер Caddy (подробнее о котором можно узнать через наш генератор Caddyfile) берет выпуск и обновление сертификатов на себя. Достаточно добавить в /etc/caddy/Caddyfile всего несколько строк:

track.example.com {
    reverse_proxy 127.0.0.1:5000 {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
    }
}

Перезагрузите службу Caddy:

sudo systemctl reload caddy

Безопасность и первичная настройка доступа в веб-панели

При первом переходе по адресу https://track.example.com вы сразу попадете в панель управления. Критически важно: по умолчанию ChangeDetection.io запускается без пароля. В версиях ниже 0.54.7 существовала уязвимость утечки переменных окружения (включая хеши паролей) через веб-интерфейс, поэтому мы используем проверенный актуальный релиз 0.60.8+ и обязаны настроить мастер-пароль немедленно до добавления каких-либо конфиденциальных URL. Если не включить авторизацию немедленно, любой посторонний пользователь сможет просматривать ваши ссылки, внедрять свои задачи или читать историю изменений.

Для включения защиты:

  1. В верхнем меню перейдите в раздел SETTINGS.
  2. В первой вкладке General найдите поле Password (блок Password protection for your changedetection.io application).
  3. Сгенерируйте надежный пароль через наш генератор паролей и укажите его в поле пароля. С этого момента при входе в панель система будет запрашивать авторизацию.
  4. В строке Time Between Check скорректируйте глобальный интервал опроса сайтов по умолчанию (например, 1 hour или 3 hours, чтобы не создавать паразитный трафик).
  5. Нажмите кнопку Save внизу страницы для применения настроек.

Рекомендация по User-Agent: Во вкладке SETTINGS > Fetching найдите параметр Default User-Agent overrides и замените стандартное значение на актуальную строку десктопного браузера (например, Chrome 132+ под Windows/macOS). Это защитит запросы от мгновенного отсечения серверами со строгой WAF-фильтрацией.

Точечное отслеживание: CSS-селекторы, XPath, JSONPath и визуальный фильтр

Если просто вставить ссылку на страницу, ChangeDetection.io будет проверять весь текст страницы целиком. Это быстро приведет к постоянным ложным срабатываниям: изменилось время в футере сайта, обновился счетчик просмотров, появился рандомный рекламный баннер или изменился CSRF-токен в скрытой форме. Чтобы мониторинг работал безупречно, необходимо изолировать целевой контент.

При добавлении нового URL (кнопка + Add URL на главной странице) или редактировании задачи во вкладке Filters & Triggers доступны следующие инструменты:

1. Интерактивный визуальный выборщик (Visual Selector)

Если для задачи включен движок WebDriver Chrome / Playwright, перейдите во вкладку Visual Filter Selector. ChangeDetection.io отрендерит снимок страницы в вашем браузере. Вы можете просто кликнуть мышью по нужному блоку (например, плашке с ценой или блоку описания релиза) — система автоматически вычислит и подставит оптимальный CSS-селектор.

2. Ручные CSS-селекторы и XPath

Для максимальной стабильности селекторы можно задать вручную:

  • CSS Selector: Укажите класс или идентификатор элемента, например: .price-current, article.release-notes или #system-status. Можно перечислить несколько блоков через запятую.
  • XPath: Применяется, если у элемента нет уникального класса: //div[contains(@class, 'status')]/span[1].

3. Очистка от мусорных элементов (Remove Elements)

В поле Remove elements во вкладке Filters & Triggers можно указать CSS-селекторы динамических элементов, которые необходимо вырезать перед сравнением версий. По умолчанию рекомендуется добавлять:

script, style, nav, footer, .cookie-banner, .advertisement, [aria-live]

4. Мониторинг REST API и JSON-ответов

ChangeDetection.io умеет отслеживать ответы сырых JSON API. Достаточно указать URL эндпоинта и в поле фильтра задать JSONPath-выражение с префиксом json:, например:

json:$.data.version
json:$[0].attributes.price

Мгновенные уведомления в Telegram через сервис Apprise

Для отправки оповещений в ChangeDetection.io встроен мощный движок Apprise, поддерживающий свыше 100 популярных сервисов (Telegram, Discord, Slack, Email, Webhooks, а также self-hosted push-сервер Ntfy). Для русскоязычных сисадминов и вебмастеров самым надежным каналом является Telegram.

Шаг 1. Получение токена бота и Chat ID

  1. Откройте Telegram и найдите бота @BotFather.
  2. Отправьте команду /newbot, укажите имя и получите токен вида 123456789:ABCdefGhIJKlmNoPQRstuVWXyz.
  3. Запустите созданного бота (нажмите Start), затем узнайте свой персональный chat_id (например, через бота @userinfobot) или ID группового чата (число с минусом, например -1001234567890).

Шаг 2. Подключение Apprise URL

Перейдите в веб-интерфейсе ChangeDetection в SETTINGS > Notifications (для глобального уведомления обо всех событиях) или в настройки конкретного URL (вкладка Notifications). Добавьте строку в формате (параметр ?format=markdown гарантирует корректную интерпретацию разметки ботом Telegram):

tgram://123456789:ABCdefGhIJKlmNoPQRstuVWXyz/-1001234567890?format=markdown

Если уведомление отправляется в личные сообщения пользователю, укажите Chat ID без минуса:

tgram://123456789:ABCdefGhIJKlmNoPQRstuVWXyz/987654321?format=markdown

Шаг 3. Настройка шаблона сообщения

В поле Notification Body настройте информативное сообщение с использованием системных переменных подстановки (убедитесь, что для уведомления выбран формат Markdown to HTML):

🔔 *Обнаружено изменение на странице!*

*Название:* {{ watch_title }}
*Ссылка:* {{ watch_url }}

*Что изменилось:*
{{ diff }}

*Текущий снимок:*
{{ current_snapshot }}

Нажмите кнопку Send test notification. В течение 1–2 секунд в ваш Telegram-чат придет тестовое уведомление с подтверждением успешной связки.

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Выбор редакции
⚡

Timeweb Cloud — Скоростные NVMe VDS

Высокая тактовая частота процессора 3.3+ ГГц обеспечивает моментальный рендеринг тяжелых страниц в безголовом браузере Chromium без задержек.

Конфигурация
1 vCPU 3.3 ГГц • 2 ГБ RAM • 25 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Надежная инфраструктура Tier III

Стабильные VDS в дата-центрах уровня Tier III с гарантированной полосой пропускания для непрерывного круглосуточного мониторинга сотен URL.

Конфигурация
1 vCPU • 2 ГБ RAM • 30 ГБ NVMe • 100 Мбит/с
Идеально для Docker
🟠

Beget — Простота и отказоустойчивость

Удобная панель управления с развертыванием Docker в один клик, автоматическими снапшотами системы и почасовой тарификацией.

Конфигурация
1 vCPU • 2 ГБ RAM • 20 ГБ NVMe • Трафик без лимита

Мониторинг цен, проверка наличия товаров и фильтры ложных срабатываний

Одной из наиболее востребованных функций ChangeDetection.io является специализированный модуль отслеживания цен и складских остатков на маркетплейсах и сайтах ритейлеров. Вместо того чтобы вручную писать регулярные выражения парсинга чисел, платформа предоставляет готовые инструменты автоматизации:

1. Автоматическое распознавание цен (Price Tracking)

В настройках конкретной задачи во вкладке General выберите процессор Re-stock & Price detection for pages with a SINGLE product. После сохранения появится специализированная вкладка Restock & Price Detection, где активируется опция Follow price changes. ChangeDetection.io использует встроенный интеллектуальный парсер валют: он автоматически вычленяет из блока текста числовые значения (игнорируя пробелы между тысячами, символы рубля, доллара или евро) и сохраняет их в виде числовой временной шкалы.

В интерфейсе появится наглядный интерактивный график изменения цены во времени, а в истории версий отобразится динамика: например, -15% (было 49 990 ₽ → стало 42 490 ₽).

2. Триггеры условий (Trigger Conditions)

Чтобы бот в Telegram не присылал сообщения при каждом незначительном колебании или повышении цены, настройте правила срабатывания:

  • Follow price changes: Отправлять уведомление при любом зафиксированном изменении стоимости.
  • Below / Above price to trigger notification: Пороговые значения — алерт отправляется строго при падении ниже или росте выше заданной суммы.
  • Threshold (%) for price changes since the previous check: Порог относительного изменения в процентах по модулю (например, значение 5% игнорирует мелкие колебания и оповещает при изменении цены от 5% в любую сторону).
  • Текстовые триггеры наличия: В стандартной вкладке Filters & Triggers поле Keyword triggers - Trigger/wait for text позволяет задать ключевые слова (В наличии|Доступен для заказа), отслеживая переход товара из статуса «Нет на складе».

Диагностика неполадок: обход защиты Cloudflare, тайм-ауты и частые ошибки

В процессе непрерывного мониторинга сторонних ресурсов могут возникать технические сложности. Разберем основные проблемы и способы их устранения:

1. Страница выдает ошибку 403 Forbidden или бесконечную загрузку Cloudflare

Если целевой ресурс защищен WAF (Cloudflare, DDoS-Guard, Qrator), встроенный HTTP-парсер будет мгновенно заблокирован. Для обхода переключите метод сбора:

  1. Откройте настройки URL и перейдите во вкладку Request.
  2. В поле Fetch method выберите WebDriver Chrome / Playwright.
  3. Во вкладке Request найдите параметр Wait seconds before extracting text и задайте значение 5 или 8 секунд, чтобы JavaScript успел пройти проверку браузерного отпечатка и отрендерить DOM.
  4. При необходимости добавьте сценарий взаимодействия: клик по кнопке «Принять cookies» (Action: Click с селектором кнопки), чтобы закрыть всплывающие модальные окна.

2. Чрезмерное потребление памяти контейнером Chromium

Если вы мониторите десятки страниц с тяжелым рендерингом, процессы Chrome могут накапливать кэш. Именно поэтому в нашем манифесте Docker Compose мы заранее предусмотрели:

  • Ограничение mem_limit: 1536m и лимит процессора cpus: 1.5.
  • Параметр MAX_CONCURRENT_CHROME_PROCESSES=4, запрещающий запуск более 4 параллельных вкладок.
  • Использование tmpfs: - /tmp для автоматической очистки временных файлов в памяти.

Если вы заметили нехватку памяти, проверьте текущее потребление ресурсов с помощью команды docker stats или установите легковесный агент Beszel для мониторинга Docker.

3. Блокировка по IP-адресу VDS и настройка прокси

При слишком интенсивном мониторинге целевой ресурс может ограничить запросы с IP-адреса хостинга. В этом случае:

  • Увеличьте интервал опроса до 30–60 минут и задайте случайный разброс времени (Jitter).
  • Подключите прокси в меню SETTINGS > CAPTCHA & Proxies. Для браузерного движка Chrome/Playwright используйте стандартные HTTP-прокси (включая формат http://user:pass@host:port) либо привязку по IP (IP-whitelisting). Обратите внимание: SOCKS5-прокси с авторизацией по логину/паролю поддерживаются только базовым HTTP-фетчером (plain requests).
  • Проверьте корректность цепочки перенаправлений через наш инструмент проверки редиректов.

Итоги: надежная автономная система веб-контроля

Развертывание ChangeDetection.io в связке с Playwright на собственном VDS превращает обычный виртуальный сервер в профессиональный центр автоматического мониторинга данных. Вы больше не зависите от дорогостоящих подписок сторонних SaaS-платформ, получаете неограниченную историю версий, надежные оповещения в Telegram и полный контроль над сетевыми запросами.

Для надежной круглосуточной работы связки выбирайте современные виртуальные серверы с быстрыми накопителями NVMe и достаточным объемом оперативной памяти (от 2 ГБ), представленные в рекомендациях выше.

Инструменты SysKit по теме статьи

Бесплатные утилиты для проверки и диагностики вашего сервера

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Сколько оперативной памяти требуется для связки ChangeDetection.io и Playwright?
Сам контейнер ChangeDetection.io на Python потребляет около 80–120 МБ RAM. Однако вспомогательный контейнер с безголовым Chromium (sockpuppetbrowser) требует для комфортной работы от 500 МБ до 1 ГБ RAM при параллельном рендеринге 2–5 страниц. Для стабильной работы рекомендуется сервер минимум с 2 ГБ RAM.
Как избежать бана по IP при частом мониторинге интернет-магазинов?
Не ставьте интервал проверки чаще 15–30 минут, настройте случайную задержку (Jitter) в настройках запроса, укажите реалистичный User-Agent современного браузера и при необходимости подключите резидентный или серверный HTTP/SOCKS5 прокси в разделе 'Proxy settings' для конкретного отслеживаемого сайта.
Почему базовый парсер показывает пустую страницу или ошибку 403, а через Playwright всё работает?
Базовый движок ChangeDetection.io отправляет стандартный HTTP-запрос библиотекой requests без выполнения JavaScript-кода и без эмуляции браузерного окружения. Большинство современных сайтов (SPA на React/Vue, защита Cloudflare/WAF) требуют выполнения скриптов для формирования DOM-дерева, с чем справляется связка с Playwright/sockpuppetbrowser.
Можно ли отслеживать только изменение чисел (например, цены товара), игнорируя текст?
Да, ChangeDetection.io поддерживает фильтры извлечения регулярными выражениями (Regex Extract), встроенный селектор цен, а также фильтрацию шума (Strip elements), что позволяет отсекать плавающие блоки со случайными баннерами, датами и счетчиками посетителей.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи