openreader/docs-site/docs/deploy/compute-worker.md
Richard R 4ddedee8ec docs(worker): document and expose JetStream storage limits for jobs and KV state
Add `COMPUTE_JOBS_STREAM_MAX_BYTES` and `COMPUTE_JOB_STATES_MAX_BYTES` to
environment example, worker server configuration, and deployment docs. These
variables allow tuning JetStream resource caps for job queue and state storage
to better fit deployment requirements.
2026-05-20 15:34:17 -06:00

4.9 KiB

title: Compute Worker (NATS JetStream)

Use this guide for COMPUTE_MODE=worker deployments where heavy compute runs outside the Next.js app server.

Overview

The compute worker handles:

  • Whisper word alignment (/align/whisper/jobs)
  • PDF layout parsing (/layout/pdf/jobs)

The app server enqueues jobs and polls status. Queue durability and retries are backed by NATS JetStream WorkQueue consumers and NATS KV.

Published image

  • App server image: ghcr.io/richardr1126/openreader
  • Compute worker image: ghcr.io/richardr1126/openreader-compute-worker
  • Compute worker image (example pinned tag): ghcr.io/richardr1126/openreader-compute-worker:refactor-ppdoclayoutv3-onnx-layout-parsing

Worker environment variables

Required:

  • COMPUTE_WORKER_TOKEN: bearer token expected by worker routes
  • NATS_URL: NATS server connection string (JetStream enabled)
  • S3_BUCKET
  • S3_REGION
  • S3_ACCESS_KEY_ID
  • S3_SECRET_ACCESS_KEY

Important

S3 credentials cannot be left blank/empty when running in worker mode. While the main Next.js server can generate random, dynamic S3 keys on-the-fly when USE_EMBEDDED_WEED_MINI=true and S3_* vars are blank, the compute worker runs in a separate process and cannot connect to SeaweedFS using those dynamically generated keys. To use the compute worker with the embedded SeaweedFS, you must configure identical, stable S3 credentials (e.g. S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY) in both the root .env and the compute worker .env files.

Common optional:

  • NATS_CREDS: raw user credentials file content (JWT + private key), ideal for cloud container environments where mounting files is difficult.
  • NATS_CREDS_FILE: path to a .creds file on the server.
  • S3_ENDPOINT (for non-AWS S3-compatible storage)
  • S3_FORCE_PATH_STYLE=true (for many S3-compatible providers)
  • S3_PREFIX=openreader
  • COMPUTE_WORKER_HOST=0.0.0.0
  • COMPUTE_WORKER_PORT=8081
  • COMPUTE_LOG_FORMAT=pretty (default) or json
  • COMPUTE_PREWARM_MODELS=true
  • COMPUTE_JOBS_STREAM_MAX_BYTES=268435456 (256MB JetStream jobs stream cap)
  • COMPUTE_JOB_STATES_MAX_BYTES=67108864 (64MB JetStream KV bucket cap)

App server environment variables (worker mode)

Set on the Next.js app server:

COMPUTE_MODE=worker
COMPUTE_WORKER_URL=http://<worker-host>:8081
COMPUTE_WORKER_TOKEN=<same-token-as-worker>

COMPUTE_MODE=worker has no local fallback. If worker is unavailable, affected requests fail.

Production notes

  • Worker mode assumes shared object storage is reachable by both app server and worker.
  • Non-exposed embedded weed mini is not supported with external worker mode.
  • Protect COMPUTE_WORKER_TOKEN and avoid exposing worker routes publicly without auth.

Health endpoints

  • GET /health/live
  • GET /health/ready

Synadia Cloud + Railway Setup (Complete Guide)

Use this end-to-end guide when your queue backend is Synadia Cloud (NGS) and your worker runs on Railway.

1. Create Synadia account and credentials

  1. Create a Synadia Cloud account and create/select your NGS environment.
  2. Create a user or service account for OpenReader compute worker access.
  3. Download the generated credentials file (usually <name>.creds) and keep it secure.

You will use:

  • NATS_URL=tls://connect.ngs.global:4222
  • The full .creds file content

2. Deploy compute worker on Railway

Create a Railway service from:

ghcr.io/richardr1126/openreader-compute-worker:refactor-ppdoclayoutv3-onnx-layout-parsing

Set the container port to 8081, then enable public networking to get a worker URL.

3. Configure Railway worker environment variables

Set these in the Railway worker service:

COMPUTE_WORKER_HOST=0.0.0.0
COMPUTE_WORKER_PORT=8081
COMPUTE_WORKER_TOKEN=<long-random-shared-token>
COMPUTE_JOBS_STREAM_MAX_BYTES=268435456
COMPUTE_JOB_STATES_MAX_BYTES=67108864

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>
S3_ENDPOINT=<optional-for-s3-compatible-providers>
S3_FORCE_PATH_STYLE=true
S3_PREFIX=openreader

Notes:

  • NATS_CREDS should be the full Synadia .creds file content, including begin/end markers.
  • Keep COMPUTE_WORKER_TOKEN identical between app server and worker.
  • If your platform supports mounted files, you can use NATS_CREDS_FILE instead of NATS_CREDS.
  • COMPUTE_JOBS_STREAM_MAX_BYTES and COMPUTE_JOB_STATES_MAX_BYTES are optional; defaults are 268435456 (256MiB) and 67108864 (64MiB).

4. Configure the OpenReader app server (worker mode)

Set these env vars on the app server:

COMPUTE_MODE=worker
COMPUTE_WORKER_URL=https://<railway-worker-domain>
COMPUTE_WORKER_TOKEN=<same-token-as-worker>

5. Verify health

After deploy, check:

  • GET https://<railway-worker-domain>/health/live
  • GET https://<railway-worker-domain>/health/ready