Changedetection.io es una aplicación de código abierto que revisa páginas web a intervalos fijos y te avisa cuando su contenido cambia. Sirve para vigilar precios, disponibilidad de productos, avisos legales o páginas de estado sin depender de un servicio externo. En este tutorial la desplegarás con Docker Compose en Ubuntu 24.04, junto a un navegador Chromium para páginas que cargan contenido con JavaScript, la publicarás detrás de Nginx con HTTPS y configurarás filtros y notificaciones.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 1 GB de RAM (el navegador Chromium consume la mayor parte).
- Un usuario no root con privilegios
sudo. - Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker.
- Un dominio o subdominio, por ejemplo
cambios.your_domain, con un registro A apuntando a la IP del servidor. - Los puertos 80 y 443 abiertos en el firewall.
Paso 1: Crear el archivo de Docker Compose
Changedetection.io guarda toda su configuración y el historial de cambios en un directorio de datos. Crea un directorio para el proyecto:
sudo mkdir -p /opt/changedetection
cd /opt/changedetection
Crea el archivo de Compose:
sudo nano /opt/changedetection/compose.yaml
Añade el siguiente contenido. El servicio sockpuppetbrowser es el Chromium que mantiene el propio proyecto para renderizar páginas con JavaScript:
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io:latest
container_name: changedetection
hostname: changedetection
volumes:
- ./datastore:/datastore
environment:
- BASE_URL=https://cambios.your_domain
- PLAYWRIGHT_DRIVER_URL=ws://sockpuppetbrowser:3000
ports:
- "127.0.0.1:5000:5000"
depends_on:
- sockpuppetbrowser
restart: unless-stopped
sockpuppetbrowser:
image: dgtlmoon/sockpuppetbrowser:latest
hostname: sockpuppetbrowser
cap_add:
- SYS_ADMIN
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1024
- SCREEN_DEPTH=16
- MAX_CONCURRENT_CHROME_PROCESSES=10
restart: unless-stopped
Sustituye cambios.your_domain por tu dominio. BASE_URL se usa para generar los enlaces que aparecen en las notificaciones. El puerto 5000 solo escucha en 127.0.0.1, así que la aplicación no queda expuesta a Internet hasta que la publiques con Nginx.
Paso 2: Arrancar los contenedores
Descarga las imágenes y arranca los servicios en segundo plano:
sudo docker compose up -d
Comprueba que los dos contenedores están en marcha:
sudo docker compose ps
NAME IMAGE STATUS
changedetection ghcr.io/dgtlmoon/changedetection.io:latest Up 20 seconds
changedetection-sockpuppetbrowser-1 dgtlmoon/sockpuppetbrowser:latest Up 21 seconds
Verifica que la aplicación responde en local:
curl -sI http://127.0.0.1:5000 | head -n 1
HTTP/1.1 200 OK
Si no responde, revisa los logs con sudo docker compose logs changedetection.
Paso 3: Publicar la aplicación con Nginx y HTTPS
Instala Nginx y Certbot con su plugin para Nginx:
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx
Crea el bloque de servidor:
sudo nano /etc/nginx/sites-available/changedetection
server {
listen 80;
listen [::]:80;
server_name cambios.your_domain;
location / {
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Las cabeceras Upgrade y Connection permiten el WebSocket que usa la interfaz para actualizar el estado de las comprobaciones en tiempo real. Activa el sitio, valida la sintaxis y recarga Nginx:
sudo ln -s /etc/nginx/sites-available/changedetection /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Abre los puertos web en UFW y solicita el certificado. Certbot modifica el bloque de servidor para servir HTTPS y redirigir HTTP:
sudo ufw allow 'Nginx Full'
sudo certbot --nginx -d cambios.your_domain
Abre https://cambios.your_domain en el navegador. Deberías ver la página principal con el campo para añadir una URL.
Paso 4: Proteger el panel con contraseña
Por defecto el panel no pide contraseña, así que cualquiera que conozca la URL podría usarlo. Ve a Settings > General, rellena el campo Password protection con una contraseña robusta y guarda. A partir de ese momento el panel pedirá la contraseña al entrar.
En la misma pestaña puedes ajustar el intervalo de comprobación por defecto (Time between check). Evita intervalos muy cortos: comprobar una web cada pocos minutos aumenta la carga y puede provocar que el sitio vigilado bloquee la IP de tu servidor.
Paso 5: Añadir la primera vigilancia
Cada URL vigilada se llama watch. En la página principal, escribe la URL en el campo superior, añade una etiqueta opcional (por ejemplo precios) y pulsa Watch. Changedetection.io hará una primera captura y a partir de ahí comparará cada comprobación con la anterior.
Para páginas que cargan el contenido con JavaScript (tiendas en React o Vue, por ejemplo), edita el watch y, en la pestaña Request, cambia el Fetch Method a la opción de Playwright/Chrome. Así la página se renderiza en el contenedor sockpuppetbrowser antes de compararse. El método HTTP simple es más rápido y consume menos memoria, así que úsalo siempre que la página funcione sin JavaScript.
Para comprobar que funciona, pulsa Recheck en el watch y abre Preview: debes ver el texto extraído de la página.
Paso 6: Filtrar solo la parte que te interesa
Vigilar una página completa genera falsos positivos por cambios en menús, banners o fechas. Edita el watch y ve a la pestaña Filters & Triggers. En el campo CSS/JSONPath/JQ/XPath Filters indica un selector por línea. Por ejemplo, para vigilar solo el precio de un producto:
.product-price
Los selectores XPath empiezan por // o por el prefijo xpath::
//span[@itemprop='price']
Para averiguar el selector correcto, abre la página en tu navegador, pulsa con el botón derecho sobre el elemento y usa Inspeccionar.
En el campo Ignore text puedes descartar líneas que cambian siempre. Las expresiones regulares se escriben entre barras. Este ejemplo ignora fechas y contadores de visitas:
/\d{1,2}\/\d{1,2}\/\d{4}/
/\d+ visitas/
Guarda y pulsa Recheck. En Preview solo debe aparecer el contenido que coincide con el filtro.
Paso 7: Configurar notificaciones
Changedetection.io envía los avisos con Apprise, que admite decenas de servicios mediante URLs. Ve a Settings > Notifications y añade una URL por línea en Notification URL List. Algunos formatos habituales:
tgram://your_bot_token/your_chat_id
discord://your_webhook_id/your_webhook_token
mailtos://your_user:[email protected]_domain?to=alertas@your_domain
ntfys://ntfy.sh/your_topic
Estos valores son marcadores de posición: sustitúyelos por el token de tu bot de Telegram, tu webhook de Discord o los datos de tu servidor SMTP. Pulsa Send test notification para comprobar que el aviso llega antes de guardar.
El cuerpo del mensaje admite variables, por ejemplo:
Cambio detectado en {{watch_title}}
{{watch_url}}
{{diff}}
Ver diferencias: {{diff_url}}
La configuración de Settings se aplica a todos los watches. Si un watch necesita un destino distinto, edítalo y define sus propias URLs en su pestaña Notifications.
Paso 8: Usar la API (opcional)
La API REST permite dar de alta watches desde scripts. Obtén la clave en Settings > API y guárdala en una variable:
export CD_API_KEY=your_api_key
Crea un watch nuevo:
curl -s -X POST "https://cambios.your_domain/api/v1/watch" \
-H "x-api-key: $CD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/precios", "title": "Precios de example.com"}'
{"uuid": "3f1b2c1e-8d4a-4a7e-9c2b-5b7e1f0a9d12"}
Lista los watches existentes para confirmar que se ha creado:
curl -s "https://cambios.your_domain/api/v1/watch" -H "x-api-key: $CD_API_KEY"
Paso 9: Copias de seguridad y actualizaciones
Todos los datos están en /opt/changedetection/datastore. Para hacer una copia, detén el servicio un momento y empaqueta el directorio:
cd /opt/changedetection
sudo docker compose stop changedetection
sudo tar czf /root/changedetection-$(date +%F).tar.gz datastore
sudo docker compose start changedetection
Para actualizar a la última versión, descarga las imágenes nuevas y recrea los contenedores:
sudo docker compose pull
sudo docker compose up -d
Solución de problemas
Las páginas con JavaScript aparecen vacías. Comprueba que el watch usa el fetcher de Playwright/Chrome y que el contenedor del navegador está en marcha con sudo docker compose ps. Revisa sus logs con sudo docker compose logs sockpuppetbrowser --tail 50.
El sitio vigilado devuelve 403 o un captcha. Algunas webs bloquean peticiones automatizadas. Aumenta el intervalo de comprobación y prueba con el fetcher de Chrome, que se parece más a un navegador real.
Las notificaciones no llegan. Usa Send test notification y revisa el mensaje de error que muestra la interfaz. Los fallos más comunes son tokens mal copiados y servidores SMTP que exigen mailtos:// (TLS) en lugar de mailto://.
Demasiados avisos por cambios irrelevantes. Restringe el watch con un filtro CSS o XPath y añade patrones en Ignore text.
Conclusión
Tienes Changedetection.io funcionando en Docker detrás de Nginx con HTTPS, con renderizado de JavaScript, filtros para reducir falsos positivos y avisos por el canal que prefieras. Como siguientes pasos puedes usar Browser Steps para vigilar páginas que requieren hacer clic o iniciar sesión, organizar los watches por etiquetas con notificaciones propias y programar la copia de datastore con un temporizador de systemd.
