Revise the compute worker deployment documentation to clarify usage scenarios, streamline environment variable instructions, and improve separation between embedded and standalone deployment modes. Remove outdated references and reformat for better readability.
4.3 KiB
| title | description |
|---|---|
| Compute Worker | Deploy the standalone worker used for Whisper alignment and PDF layout parsing. |
Use this guide when OpenReader runs compute as a separate service. For the default embedded/local flow (pnpm dev or pnpm start without COMPUTE_WORKER_URL), configure the root .env instead and see Local Development.
What the worker does
- Runs Whisper word alignment jobs
- Runs PDF layout parsing jobs
- Stores durable job state in NATS JetStream and NATS KV
The app server submits work to POST /ops and listens for updates on GET /ops/:opId/events.
When to use it
- Required for Vercel-style deployments where heavy compute must run outside the app server
- Useful when you want a dedicated compute host
- Not needed for the default embedded local flow
Container image
ghcr.io/richardr1126/openreader-compute-worker:latest
Worker environment
Required worker variables:
COMPUTE_WORKER_TOKEN=...
NATS_URL=nats://...
S3_BUCKET=...
S3_REGION=...
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
:::important
compute/worker/.env* is only for standalone worker deployments.
- Embedded/local mode: configure the root
.envonly. - External worker mode: set
COMPUTE_WORKER_URLandCOMPUTE_WORKER_TOKENon the app, and worker runtime values on the worker service. - Keep shared values aligned across app and worker:
COMPUTE_WORKER_TOKEN,S3_*,COMPUTE_WHISPER_TIMEOUT_MS,COMPUTE_PDF_TIMEOUT_MS, andCOMPUTE_OP_STALE_MS. :::
Common optional variables:
NATS_CREDSorNATS_CREDS_FILES3_ENDPOINT,S3_FORCE_PATH_STYLE=true,S3_PREFIX=openreaderCOMPUTE_WORKER_HOST=0.0.0.0PORT=8081for local/manual runs. Platforms like Railway usually injectPORT.LOG_FORMAT=jsonandCOMPUTE_LOG_LEVEL=infoCOMPUTE_PREWARM_MODELS=trueCOMPUTE_JOB_CONCURRENCY=1COMPUTE_WHISPER_TIMEOUT_MS=30000COMPUTE_PDF_TIMEOUT_MS=300000COMPUTE_PDF_JOB_ATTEMPTS=1COMPUTE_JOBS_STREAM_MAX_BYTES=268435456COMPUTE_EVENTS_STREAM_MAX_BYTES=134217728COMPUTE_JOB_STATES_MAX_BYTES=67108864COMPUTE_NATS_REPLICAS=1COMPUTE_OP_STALE_MS=1800000WHISPER_MODEL_BASE_URLPDF_LAYOUT_MODEL_BASE_URL
If you need the broader app config reference, see Environment Variables.
App server environment
Set these on the Next.js app server:
COMPUTE_WORKER_URL=https://worker.example.com
COMPUTE_WORKER_TOKEN=<same-token-as-worker>
# Optional shared overrides:
# COMPUTE_WHISPER_TIMEOUT_MS=30000
# COMPUTE_PDF_TIMEOUT_MS=300000
# COMPUTE_OP_STALE_MS=1800000
Notes:
- Model artifact overrides (
WHISPER_MODEL_BASE_URL,PDF_LAYOUT_MODEL_BASE_URL) belong on the worker service, not the app server. - There is no app-local compute fallback once
COMPUTE_WORKER_URLis set. If the worker is unavailable, worker-backed requests fail.
Deployment notes
- App and worker must share the same object storage.
- Embedded
weed miniis not supported for external worker mode. - Protect
COMPUTE_WORKER_TOKENand do not expose worker routes without auth. - The worker connects to NATS lazily and disconnects after 120 seconds of full idle time. That allows platforms like Railway to sleep the service, but the first request after a cold start will be slower.
Health endpoints
GET /health/livereturns{ ok: true }.GET /health/readyreturns{ ok: true, natsConnected }and reflects the current NATS session without forcing a reconnect.
Railway + Synadia example
Deploy the worker image to Railway and set worker env vars similar to:
COMPUTE_WORKER_HOST=0.0.0.0
COMPUTE_WORKER_TOKEN=<shared-token>
NATS_URL=tls://connect.ngs.global:4222
NATS_CREDS="-----BEGIN NATS USER JWT-----
...
------END USER NKEY SEED------"
S3_BUCKET=<bucket>
S3_REGION=<region>
S3_ACCESS_KEY_ID=<key>
S3_SECRET_ACCESS_KEY=<secret>
# Optional:
# S3_ENDPOINT=https://...
# S3_FORCE_PATH_STYLE=true
# S3_PREFIX=openreader
If your platform supports mounted files, you can use NATS_CREDS_FILE instead of NATS_CREDS.
Set these on the OpenReader app server:
COMPUTE_WORKER_URL=https://<railway-worker-domain>
COMPUTE_WORKER_TOKEN=<same-token-as-worker>
Verify the worker after deploy:
GET https://<railway-worker-domain>/health/liveGET https://<railway-worker-domain>/health/ready