Skip to content

Self-hosting the scanner

The scanner is a single container: a FastAPI service with Playwright and Chromium inside. Snapshots live on a volume you control.

Terminal window
docker build -t wpdiff-scanner ./prototype
docker run -d \
--name wpdiff-scanner \
-p 8787:8787 \
-v wpdiff-data:/data \
-e WPDIFF_TOKEN=$(openssl rand -hex 24) \
wpdiff-scanner

Or with Docker Compose:

services:
scanner:
build: ./prototype
ports:
- "8787:8787"
volumes:
- wpdiff-data:/data
environment:
WPDIFF_TOKEN: change-me-to-a-long-random-value
restart: unless-stopped
volumes:
wpdiff-data:

Check it responds:

Terminal window
curl http://localhost:8787/api/health
VariableDefaultPurpose
WPDIFF_TOKENdev-tokenBearer token clients must present. Always set your own.
WPDIFF_DATA/data in the imageSnapshot and diff storage root

The container speaks plain HTTP. In production put a reverse proxy with TLS in front of it, for example Caddy:

scanner.example.com {
reverse_proxy localhost:8787
}

Then use https://scanner.example.com as the Backend URL in the plugin.

Snapshots are plain files under the data volume:

/data/<host>/
runs/<run-id>/
manifest.json
pages/<slug>.png
diffs/<from>_vs_<to>/
summary.json
<slug>-baseline.png
<slug>-current.png

Back up the volume if you care about snapshot history. Deleting a run’s directory removes it from the timeline.

Full page screenshots of content heavy pages run to a few megabytes each. As a rough guide, a 50 page site scanned weekly uses in the order of 10 GB a year before any pruning. Automatic retention is on the roadmap; for now prune old run directories yourself.