The shortest supported VPS deployment is a Docker container with a persistent /datastore volume, bound to localhost and placed behind a TLS reverse proxy. Add the project’s Playwright/browser fetcher only for pages that require JavaScript rendering or browser actions.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
This guide covers installation, persistent storage, reverse-proxy settings, JavaScript watches, notifications, tuning, upgrades and the failure modes most likely to matter on a self-managed server.
As an Amazon Associate I earn from qualifying purchases.
Free tools Windows power users keep installed
One-click scans. No signup required.
What you are deploying
changedetection.io is a self-hosted website change-monitoring service. It periodically fetches URLs, compares the resulting content and can notify you when a selected part of a page changes. A basic deployment uses ordinary HTTP fetching. A second, browser-enabled service can render JavaScript-heavy pages and perform browser steps, but it adds another container and consumes more server resources.
For a VPS, Docker is the practical starting point because the application, its dependencies and its restart policy are defined together. The project also supports a Python/pip installation, which can suit an existing Python environment, but it requires you to manage the runtime and process service yourself.
#1 Best Overall
- Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
Choose the deployment shape first
| Characteristic | HTTP-only container | Browser-enabled deployment |
|---|---|---|
| Containers | One application container | Application plus the browser-fetcher service from the project’s official Compose configuration |
| JavaScript rendering | Limited to what the ordinary HTTP fetcher can retrieve | Designed for pages that build their content in a browser |
| Browser steps and screenshots | Not available for targets that need a real browser | Supports browser-oriented fetching, steps and screenshot workflows documented by the project |
| CPU and memory demand | Lower and easier to operate | Higher; browser processes can be substantial, especially with several concurrent watches |
| Operational complexity | One image, one port and one persistent volume | Multiple services, service dependency, browser-specific variables and more logs to monitor |
Start with HTTP-only fetching. Move a watch to the browser fetcher when the saved response is missing content that appears only after JavaScript runs, or when the watch requires browser actions. Running a browser for every watch wastes resources and makes failures harder to isolate.
Prepare the VPS
Use a current Linux system
Provision a current Linux VPS and apply its security updates. Install Docker Engine and Docker Compose support by following the official instructions for your distribution. The changedetection.io project assumes Docker or Python; it does not prescribe one universal VPS distribution command.
Create an application directory
Keep the Compose file, proxy configuration and operational notes in a dedicated directory. Do not treat the container filesystem as storage. The only data that must survive replacement is the mounted datastore, so plan a backup location before you create watches.
Decide how the public hostname will work
Choose a DNS name for the service and point it at the VPS. The application should listen only on 127.0.0.1; Nginx, Caddy, Traefik or another reverse proxy should own ports 80 and 443, obtain the certificate and forward requests to the local application port.
Install the minimal Docker deployment
Run the official standalone container
The project documents this standalone command:
docker run -d --restart always
-p "127.0.0.1:5000:5000"
-v datastore-volume:/datastore
--name changedetection.io
dgtlmoon/changedetection.io
The localhost binding is deliberate. It prevents direct Internet access to the application while still allowing a reverse proxy on the same VPS to reach it. The named volume is equally important: watches, previous snapshots and application state are stored under /datastore. Recreating a container without that mount creates an apparently fresh installation.
Use Docker Compose for repeatable changes
A small Compose file makes upgrades and environment changes less error-prone:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteRank #2
- Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
services:
changedetection:
image: dgtlmoon/changedetection.io
container_name: changedetection.io
restart: unless-stopped
ports:
- "127.0.0.1:5000:5000"
volumes:
- datastore-volume:/datastore
volumes:
datastore-volume:
Save it as compose.yml and start it with docker compose up -d. Check startup output with docker compose logs -f changedetection; with the standalone command, use docker logs -f changedetection.io. The exact image tag and browser-service definitions should be kept aligned with the project’s current deployment documentation.
Protect and back up the datastore
Why persistence is non-negotiable
Every watch depends on the datastore. It contains the watch definitions, historical comparison state and related settings. A container update is safe only when the replacement mounts the same volume at /datastore. Never run a second container with an empty volume and assume the old watches will reappear.
Back up before upgrades
Stop or quiesce the application according to your backup method, archive the complete named volume, and store a copy outside the VPS. Test that the archive can be read and that a restore produces the expected watch list. Keep at least one backup from before each image upgrade and rotate older copies according to the value of your monitoring history.
Upgrade without deleting state
- Read the release notes for compatibility changes and note the current image reference.
- Back up
datastore-volume. - Pull the new image with
docker compose pull, or pull it explicitly if you use the standalone container. - Recreate the application while retaining the same volume:
docker compose up -dfor Compose, or stop, remove and rerun the standalone container with the identical-v datastore-volume:/datastoremount. - Open the UI, confirm that watches and notification settings are present, then inspect logs for migration or fetch errors.
Put the application behind a reverse proxy
Proxy to localhost and terminate TLS
Configure the proxy’s public virtual host for your DNS name, issue a valid certificate, and forward requests to http://127.0.0.1:5000. Preserve the original host and protocol in forwarded headers. A minimal Nginx location has the following shape:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Adapt the syntax to your proxy and its certificate automation. Keep the application port closed to the public Internet; expose only the proxy’s HTTP and HTTPS ports through the VPS firewall.
Set the public URL and forwarded-header handling
Set BASE_URL to the public URL when generated links, including links used in notifications, must point to the HTTPS hostname rather than localhost. Set USE_X_SETTINGS=1 so the application respects forwarded host, path-prefix and protocol headers from the reverse proxy. Without these settings, links can contain the wrong scheme or host, and an installation mounted below a URL prefix can generate incorrect paths.
Rank #3
- CanaKit Raspberry Pi 5 Essentials Starter Kit
If you put the service under a subdirectory instead of its own hostname, make sure the proxy forwards the prefix consistently and that the application’s base URL reflects it. A dedicated hostname is usually simpler because it avoids prefix-rewrite mistakes.
Check the proxy before adding watches
- Browse to the public HTTPS hostname and confirm the login or application page loads.
- Verify that the certificate matches the hostname and renews through your chosen proxy workflow.
- Inspect generated links for
https://and the public hostname. - Confirm that direct access to port 5000 from another machine fails.
Add JavaScript rendering only where it is needed
Recognize an HTTP-fetching limitation
An ordinary HTTP fetcher receives the server response but does not behave like a full browser. If the response contains an empty application shell and the visible text appears only after scripts execute, an HTTP-only watch may never see the content you intend to monitor. The same applies to targets that require clicks, scrolling or other browser steps.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallEnable the project’s browser service
The official Compose configuration documents Playwright and other browser-service options, including the dependency relationship between the application and browser service. Start from that current configuration rather than inventing a service name or image, then add only the browser service and variables you need. Keep the application’s persistent /datastore mount unchanged.
After starting the additional service, assign the browser fetcher to the individual watches that need it. Leave static pages on the ordinary fetcher. Watch CPU and memory usage while several browser checks run together; browser processes can exhaust a small VPS sooner than the application container itself.
Validate a browser watch
- Open the target page in a normal browser and identify the text or element that should change.
- Create the watch and select the browser-capable fetch method documented by the project.
- Use a stable selector or filter rather than the entire page when possible, so layout changes do not create noisy alerts.
- Save the watch, trigger or wait for a check, and compare the captured result with what a normal browser displays.
- Review both application and browser-service logs if the page times out, remains blank or fails during a browser step.
Create watches and notifications
Choose the smallest useful change region
In the watch editor, enter the URL, choose the fetch method and set a selector or filter for the content that matters. Monitoring a price, release date, stock label or patch note is generally more reliable when the watch is limited to that element instead of the entire document. Set a polling interval that respects the target site and your server capacity.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Configure notification URLs
Notification URLs are configured per watch in that watch’s edit interface. The project describes entering one or more notification URLs there. Its API v1 exposes notification endpoints using Apprise notification syntax, allowing the same notification system to be managed programmatically.
Rank #4
- All-in-One Complete Kit: This SANOOV RPi 5 bundle comes with Raspberry Pi 5 4GB RAM single board, active cooler, durable ABS case and screwdriver. No extra parts needed, ready to use right out of the box for beginners and hobbyists
- Powerful Single Board Computer: Equipped with 4GB RAM and high-performance processor, delivers fast running speed for 4K playback, AI projects, programming and daily computing tasks. SANOOV for raspberry pi 5 4GB is equipped with broadcom 64 quad-core Arm Cortex A76 processor with gigabit ethernet and upgraded with IEEE 802.11ac Wi-Fi, Bluetooth 5.0 dual-band 2.4Ghz and 5Ghz and Power Over Ethernet (POE). Upgrading delivers 2-3 x speed vs Pi 4, redefining the experience
- Efficient Active Cooler: Effectively lowers operating temperature and prevents performance throttling. Runs quietly even under long-time heavy load, ensures stable operation all day long. SANOOV RPi 5 4GB kit offer an active cooler, which combines an aluminium heatsink with a high-performance PWM fan. Active cooler is fully compatible with the Pi OS, which can effectively reduce the temperature of RPi5 and ensure its good performance during long-term high load operation
- Sturdy ABS Protective Case: Well-fitted for Raspberry Pi 5 board, can be secured with 4 screws to effectively protect the Pi 5 motherboard from damage, reserves full access to all ports and buttons. SANOOV uses ABS material to produce the case, which has a softer texture and feel. Meanwhile, SANOOV case adopts a layered design for easy disassembly and installation. (Tip: The Case cannot install M.2 HAT Add on Board and Solid State Drive!)
- Wide Application & Full Compatibility: Seamlessly compatible with official OS and mainstream peripheral accessories for Raspberry Pi 5. Whether you are a beginner, student, electronics hobbyist or professional developer, this all-in-one kit meets your diverse needs. It excels in IoT projects, robotics design, retro gaming devices, home media servers and other DIY creations. Backed by a large global community, you can easily find guides, technical support and shared projects online
Store notification URLs as secrets. Restrict access to the application and API, and avoid placing tokens in shell history or publicly readable Compose files. Send a test notification from a low-risk watch before relying on alerts for an important change.
Tune the installation for your workload
The official Compose configuration exposes the following controls. Defaults shown here are configuration defaults, not capacity guarantees or recommended limits for every VPS.
| Variable | Documented default or role | How to use it |
|---|---|---|
FETCH_WORKERS |
10 in the documented Compose defaults |
Controls concurrent fetching. Reduce it when the VPS or target sites are overloaded; increase cautiously only after observing stable CPU, memory and network use. |
MINIMUM_SECONDS_RECHECK_TIME |
3 seconds in the documented defaults |
Sets the minimum recheck interval. A higher value reduces request pressure and prevents an aggressive schedule. |
PAGE_WATCH_LIMIT |
100 in the documented defaults |
Caps the number of watches. Treat it as an application setting, not a promise that a VPS can process 100 active watches comfortably. |
TZ |
Timezone setting | Use the timezone you want for schedules, timestamps and logs. |
LC_ALL |
Locale setting | Set it when comparisons or date formatting depend on a particular locale. |
SCREENSHOT_MAX_HEIGHT |
16000 in the documented defaults |
Limits screenshot height. Lower it if very tall captures consume excessive memory. |
HTTP_PROXY, HTTPS_PROXY, NO_PROXY |
Proxy environment variables | Use them when outbound requests must traverse a proxy, and list local destinations in NO_PROXY as appropriate. |
Change one variable at a time, restart the service, and watch logs and resource usage. There is no canonical CPU/RAM minimum or guaranteed watch-count figure published for VPS deployments, so capacity must be established from your URLs, intervals, browser usage and concurrency.
Secure the public service
- Bind the application to localhost and expose it through the reverse proxy only.
- Allow only the proxy’s public ports in the VPS firewall; keep Docker’s internal application port private.
- Use HTTPS and verify certificate renewal.
- Enable and verify the application’s authentication settings before sharing the hostname.
- Protect API credentials and notification tokens.
- Back up the datastore before upgrades and retain an off-server copy.
- Set a restart policy and confirm that the service returns after a VPS reboot.
- Review proxy, application and browser-service logs after configuration changes.
These are operational safeguards rather than a single hardened checklist published by the project. Apply the controls that match the sensitivity of the pages and notifications you monitor.
Troubleshoot the common failures
The proxy returns 502 or connection refused
Confirm that the container is running, that it is listening on port 5000, and that the proxy runs on the same VPS or can reach the configured address. Check the container logs and verify that the proxy target is 127.0.0.1:5000, not an old container address.
All watches disappeared after an update
Inspect the container’s mounts. The running container must mount the original named volume at /datastore. If a new volume was created accidentally, stop the container and restore the pre-upgrade datastore backup before creating more watches.
Best Value
- 【What you Get】You will get 1*Pi 5 8GB Single Board,1*RasTech Case,1*Active Cooler,1*Screwdriver,1*Installation instructions,12-month free warranty, lifetime service, 24-hour prompt and friendly response.
- 【More Connectors】There are two USB 3.0 ports(5Gbps simultaneously) and two USB 2.0 ports, which triple total bandwidth ,support any combination of up to two cameras or displays. Peak SD card performance is doubled through support for the SDR104 high-speed mode. It provides a smooth desktop experience for you. Offer Gigabit Ethernet and a PCIe interface, along with dual-band Wi-Fi and Bluetooth 5.0/BLE wireless capability. The RasTech Pi 5 Kit use the new 27W 5.1V 5A USB-C power connector.
- 【 Support Dual 4Kp60 Display 】Each of the two microHDMI sockets can control a 4K display at 60 Hertz, now support HDR, offering super HD video for media streaming projects. RPi 5 is the first RPi model that comes with a PCI Express port (PCIe 2.0 x1 with 500 MB/s) to attach SSDs (requires separate M.2 HAT).
- 【 Excellent Chips And Applications】Pi 5 is a full-size Pi computer using silicon built in-house at Pi. The RP1 “southbridge” provides the bulk of the I/O capabilities for Pi 5. Pi 5 is more friendly and convenient in the development of Internet of Things, Web development, machine identification, automatic control and other electronic equipment applications and network.
- 【 Faster CPU, Better GPU 】 Pi 5 features a Broadcom BCM2712 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz, it delivers a 2–3× increase in CPU performance relative to RaspberryPi 4. The 800MHz VideoCore VII GPU is compatible to OpenGL ES 3.1 and Vulkan 1.2, substantial uplift in graphics performance. Pi 5 Offers lightning-fast CPU speed, a PCI Express interface, a Real Time Clock (RTC) and a power button and runs significantly cooler than Pi 4.
JavaScript content is missing
Move that watch to the documented browser fetcher, confirm the browser service is running, and inspect browser-service logs for timeouts or failed steps. Do not enable browser fetching globally unless the workload requires it.
Generated links use localhost or HTTP
Set BASE_URL to the public HTTPS URL, set USE_X_SETTINGS=1, and verify that the proxy forwards host and protocol headers. Restart the application after changing environment variables.
Checks are too slow or the VPS is overloaded
Reduce FETCH_WORKERS, raise MINIMUM_SECONDS_RECHECK_TIME, narrow selectors, and reserve the browser service for JavaScript-dependent watches. Check whether a small number of browser pages are consuming most of the available memory.
Notifications do not arrive
Reopen the watch’s edit interface and validate each notification URL. Check application logs, test the destination independently, and confirm that outbound proxy variables are not preventing the notification request. API-managed notifications must use the project’s Apprise syntax.
A practical deployment sequence
- Provision and update the VPS, then install Docker Engine and Compose support.
- Create an application directory and decide where off-server datastore backups will live.
- Start the HTTP-only container with localhost port binding and a named
/datastorevolume. - Place a TLS reverse proxy in front, set
BASE_URLandUSE_X_SETTINGS=1, and restrict the firewall. - Log in, create one simple watch and verify that a controlled change produces a notification.
- Add the official browser-service configuration only for pages that need JavaScript or browser steps.
- Tune workers, intervals, watch limits, timezone, locale, screenshot height and proxy variables to the actual workload.
- Back up the datastore, test restart behavior and document the upgrade and restore procedure.
The Bottom Line
For most VPS users, run changedetection.io in Docker with /datastore on a persistent volume, bind it to localhost, and let a reverse proxy handle HTTPS. Add the official Playwright/browser service selectively for JavaScript pages, then tune concurrency and intervals from observed resource use rather than treating the documented defaults as capacity guarantees.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




