PixelProbe is a self-hosted media checker. It scans video, image, and audio libraries for corruption, keeps scan history, and rechecks stored files for content changes.
- Features
- How it works
- Requirements
- Quick start
- Documentation
- Contributing
- Disclaimer
- License
- LLM disclosure
Detection
- FFmpeg validation for video and audio, plus PIL and ImageMagick decoding for images
- Warning and corruption verdicts kept separate
- Rolling hashes that flag content changes without a matching modification-time change
- Exclusions and per-finding mark-as-good overrides
Scanning and recovery
- Asynchronous discovery, chunked Celery scans, progress heartbeats, and restart recovery
- Scheduled scans, scoped maintenance, and a rolling integrity queue with optional time budgets
- Immutable run membership and observed outcomes for new scan reports
- Orphan cleanup removes inventory records only after filesystem evidence supports the decision. It never removes media files.
Operations
- PostgreSQL-backed reports, audit events, API tokens, and notification delivery records
- Email, Pushover, ntfy, webhook, and Healthchecks.io integrations
- JSON and PDF reports. Complete JSON exports stream durable history; visible and PDF detail is bounded.
- A scan request creates asynchronous work. A successful HTTP response means work was accepted, not that media validation finished.
- Discovery records eligible paths and creates durable run membership.
- Celery workers claim chunks and run the media checks.
- Completion writes a report from the run snapshot. It does not reconstruct history from current library rows.
- The integrity queue later hashes recorded files. It reports cumulative attempts and successful verification separately from the latest error and unreadable outcomes.
See How it works and Operational evidence for recovery limits and historical-report behavior.
- Docker and Docker Compose
- A readable media directory on the host
- PostgreSQL and Valkey are included in the Compose stack
The app and worker run as a non-root UID/GID. The media mount is read-only. The host instance directory must be writable by the configured PUID:PGID.
Clone the repository or otherwise obtain its docker-compose.yml, then create a local .env from the example. Do not overwrite an existing .env; preserve it and review its values before changing anything. Keep SESSION_COOKIE_SECURE=true when accessing PixelProbe through HTTPS. For a local plain-HTTP deployment only, set it to false explicitly.
git clone https://github.com/ttlequals0/PixelProbe.git
cd PixelProbe
[ ! -e .env ] || { echo ".env already exists; review it instead of overwriting it"; exit 1; }
cp .env.example .envBefore startup, edit .env: replace SECRET_KEY and POSTGRES_PASSWORD, set MEDIA_PATH, and choose PUID and PGID. Create the host runtime directory and make it writable by those configured values. The Compose default is 10001:10001.
mkdir -p instance
# Replace 10001:10001 if .env uses different PUID:PGID values.
sudo chown 10001:10001 instance
docker compose up -dChange SESSION_COOKIE_SECURE=false only for local plain HTTP. Open http://localhost:5000, create the first administrator, and start a scan.
The default Compose configuration runs the web service with the scheduler disabled and the Celery worker as the scheduler owner. Both services use the same media mount and identity. See Configuration before changing concurrency, memory limits, or database pools.
| Topic | Description |
|---|---|
| Installation | Docker and manual setup |
| Configuration | Effective Compose values, cookies, permissions, schedules, and notifications |
| How it works | Discovery, chunks, validation, reports, and recovery |
| Operational evidence | Async contract, immutable history, integrity meanings, restore verification |
| API reference | Authentication, permissions, routes, and automation |
| OpenAPI specification | Machine-readable route and field coverage |
| Troubleshooting | Startup, worker, mount, and recovery checks |
| Developer guide | Local development and tests |
Read CONTRIBUTING.md. Run Python tests and the frontend build before opening a pull request.
source venv/bin/activate
python -m pytest tests/ -q
npm ci
npm run buildReview scan and cleanup results before acting. PixelProbe records observations about files and inventory. It cannot prove that a missing path was deliberately deleted rather than temporarily unreachable.
MIT. See LICENSE. Copyright is held by PixelProbe contributors.
This project was developed using AI agents as a pair programmer. It was NOT vibe coded. For context, I'm a systems engineer who also writes code professionally with 15+ years of experience. The codebase follows engineering best practices, and all architecture and design decisions were made by me, not by AI. All code generated by LLMs was reviewed and tested by me, a human.