Docker
Reader ships with a production-ready Dockerfile and compose file inexamples/deployment/docker/ in the GitHub repo.
docker-compose.yml
Critical Docker constraints
These are not optional - Reader will fail in subtle ways without them:platform: linux/amd64- Chromium is bundled as x86_64 only. On Apple Silicon Macs, Docker will emulate x86_64 (slow); on a remote x86_64 Linux host, it runs natively.shm_size: 2gb- Chrome uses/dev/shmheavily. The Docker default of 64 MB causes crashes with unhelpful errors.seccomp:unconfinedandcap_add: SYS_ADMIN- required for the Chrome sandbox. Without these, Chrome fails to spawn child processes.- Base image:
node:22-slimplus Chrome system libraries (installed in the Dockerfile).
Running it
ReaderClient. Adapt it to your needs.
Bare metal Linux
Install directly on a Linux server if you don’t want Docker.Run as a systemd service
Create/etc/systemd/system/reader.service:
Production tuning
Memory
Each browser instance uses 300-500 MB. Plan for:size: 5- 2-3 GB RAM headroomsize: 10- 4-6 GB RAM headroomsize: 20- 8-12 GB RAM headroom
Monitoring
ExposePoolStats via a /health endpoint in your app. Watch for:
queueLength > 0 sustained→ scale upunhealthy > 0 sustained→ something is causing browser crashesavgRequestDurationclimbing → target sites changed, retries are kicking in
Graceful shutdown
In Node apps, always close the client on shutdown:Where to go next
Browser Pool
Tune pool size for your workload.
Proxy Configuration
Add proxy rotation for production scraping.

