docs/env: clarify embedded vs external worker env ownership

This commit is contained in:
Richard R 2026-05-26 17:16:38 -06:00
parent a073fb63a3
commit e3ac1b1dac
6 changed files with 96 additions and 18 deletions

View file

@ -79,6 +79,8 @@ IMPORT_LIBRARY_DIRS=
# Heavy compute is always worker-backed.
# App server calls compute-worker over HTTP for ONNX whisper alignment + PDF layout parsing.
# Embedded/local (`pnpm dev` / `pnpm start` without COMPUTE_WORKER_URL) uses this same file.
# `compute/worker/.env*` is only for standalone external worker deployments.
# In single-container self-host setups, run compute-worker + NATS alongside the app and
# point COMPUTE_WORKER_URL at that internal worker endpoint.
# Required:

View file

@ -1,3 +1,7 @@
# Standalone compute-worker env.
# Used only when running compute-worker as a separate service/container.
# Not used by app embedded worker startup via `pnpm dev` / `pnpm start`.
# Compute worker bind
# Platform note:
# - Local/manual: keep PORT=8081

View file

@ -1,7 +1,8 @@
title: Compute Worker (NATS JetStream)
---
Use this guide for worker-backed deployments where heavy compute runs outside the Next.js app server.
Use this guide when compute-worker runs as a standalone service outside the Next.js app server.
For embedded/local startup (`pnpm dev` / `pnpm start` without `COMPUTE_WORKER_URL`), use root `.env` instead.
## Overview
@ -30,9 +31,12 @@ Required:
- `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.
> This file (`compute/worker/.env*`) is only for standalone worker deployments.
> In embedded/local startup, app entrypoint spawns worker with the already-resolved root `.env` values.
> For standalone worker deployments, keep shared app/worker values aligned:
> - `COMPUTE_WORKER_TOKEN`
> - shared object storage settings (`S3_*`)
> - shared timeout/stale settings (`COMPUTE_WHISPER_TIMEOUT_MS`, `COMPUTE_PDF_TIMEOUT_MS`, `COMPUTE_OP_STALE_MS`)
Common optional:
@ -86,6 +90,16 @@ Set the same value on app + worker envs.
There is no app-local compute fallback. If worker is unavailable, affected requests fail.
## Config ownership summary
- Embedded/local startup (`pnpm dev` / `pnpm start`, no `COMPUTE_WORKER_URL`):
- Configure root `.env` only.
- `compute/worker/.env*` is ignored.
- Standalone external worker service:
- Configure app root `.env` with `COMPUTE_WORKER_URL` + `COMPUTE_WORKER_TOKEN`.
- Configure worker service env (`compute/worker/.env*` or platform env).
- Keep shared values aligned (`COMPUTE_WORKER_TOKEN`, `S3_*`, timeout/stale values).
## Production notes
- Worker mode assumes shared object storage is reachable by both app server and worker.

View file

@ -127,7 +127,8 @@ If you need mirrors or pinned artifact locations, set `WHISPER_MODEL_BASE_URL` i
<details>
<summary><strong>External compute worker dev stack (optional)</strong></summary>
Use this when you want durable compute with NATS JetStream + KV while keeping Next.js on native host `pnpm dev`.
Use this only when you intentionally run compute-worker as a separate service.
Default local flow does not need `compute/worker/.env`; embedded worker startup reads root `.env`.
Full worker deployment details are in [Compute Worker (NATS JetStream)](./compute-worker).
Start only NATS + compute-worker via compose watch:
@ -137,7 +138,7 @@ docker compose --env-file compute/worker/.env -f compute/worker/docker-compose.y
# or: pnpm compute:dev:watch
```
`compute/worker/.env.example` contains a starter config. Copy it to `compute/worker/.env` and adjust values for your environment.
`compute/worker/.env.example` contains a starter config for standalone worker service deployments.
Run the main app separately on the host:
@ -145,7 +146,7 @@ Run the main app separately on the host:
pnpm dev
```
For app server worker mode, set:
For app -> external worker routing, set in root `.env`:
```env
COMPUTE_WORKER_URL=http://localhost:8081
@ -153,7 +154,7 @@ COMPUTE_WORKER_TOKEN=<same-token-used-by-worker>
```
Worker mode requires worker-reachable shared object storage (S3-compatible endpoint).
Non-exposed embedded `weed mini` is not a supported topology for external worker mode.
For external worker mode, object storage must be shared/reachable by both app and worker services.
</details>
@ -182,7 +183,15 @@ cp .env.example .env
Then edit `.env`.
Required compute worker connectivity (all modes):
Default embedded worker flow (no external worker URL):
```env
# Leave COMPUTE_WORKER_URL unset.
# Entry point auto-starts embedded worker+NATS when available.
START_EMBEDDED_COMPUTE_WORKER=
```
External worker flow:
```env
COMPUTE_WORKER_URL=http://localhost:8081
@ -245,7 +254,7 @@ S3_SECRET_ACCESS_KEY=your-secret-key
```
</TabItem>
<TabItem value="worker-mode" label="External Worker + NATS">
<TabItem value="worker-mode" label="External Worker Service">
```env
API_BASE=http://host.docker.internal:8880/v1
@ -292,6 +301,9 @@ Learn about migration behavior and commands in [Migrations](../configure/migrati
pnpm dev
```
If you use embedded worker startup (no `COMPUTE_WORKER_URL`) and the host is missing `nats-server`,
install `nats-server` locally or switch to external worker mode.
</TabItem>
<TabItem value="prod" label="Build + Start">

View file

@ -53,8 +53,14 @@ For auth-enabled deployments, use **Settings → Admin** as the primary source o
| `RUN_FS_MIGRATIONS` | Storage migrations | `true` | Set `false` to skip startup filesystem -> S3/DB migration pass |
| `IMPORT_LIBRARY_DIR` | Library import | `docstore/library` fallback | Set a single server library root |
| `IMPORT_LIBRARY_DIRS` | Library import | unset | Set multiple roots (comma/colon/semicolon separated) |
| `COMPUTE_WORKER_URL` | Heavy compute backend | unset | Required; base URL for external compute worker |
| `COMPUTE_WORKER_TOKEN` | Heavy compute backend | unset | Required bearer token for external compute worker auth |
| `COMPUTE_WORKER_URL` | Heavy compute backend | unset | Set only for standalone external compute worker; leave unset for embedded worker startup |
| `COMPUTE_WORKER_TOKEN` | Heavy compute backend | unset (auto-generated in embedded startup) | Required for standalone external compute worker auth; must match worker |
| `START_EMBEDDED_COMPUTE_WORKER` | Heavy compute backend | auto (`true` when `COMPUTE_WORKER_URL` unset) | Set `false` to disable embedded worker startup and require external worker URL/token |
| `EMBEDDED_COMPUTE_WORKER_PORT` | Heavy compute backend | `8081` | Override embedded worker bind port |
| `EMBEDDED_NATS_PORT` | Heavy compute backend | `4222` | Override embedded NATS client port |
| `EMBEDDED_NATS_MONITOR_PORT` | Heavy compute backend | `8222` | Override embedded NATS monitor port |
| `EMBEDDED_NATS_STORE_DIR` | Heavy compute backend | `docstore/nats/jetstream` | Override embedded JetStream storage directory |
| `NATS_URL` | Heavy compute backend | `nats://127.0.0.1:4222` in embedded startup | Optional override for embedded startup or required on standalone worker service |
| `COMPUTE_JOB_CONCURRENCY` | Heavy compute backend | `1` | Worker-side shared compute concurrency cap |
| `COMPUTE_WHISPER_TIMEOUT_MS` | Heavy compute backend | `30000` | Shared whisper alignment timeout budget (worker + worker client wait budget) |
| `COMPUTE_PDF_TIMEOUT_MS` | Heavy compute backend | `300000` | Shared PDF idle-timeout budget (worker + worker client wait budget) |
@ -355,17 +361,57 @@ Multiple library roots for server library import.
### COMPUTE_WORKER_URL
Base URL for external compute worker mode.
Base URL for standalone external compute worker mode.
- Required
- Leave unset for embedded/local startup (`pnpm dev` / `pnpm start`) so entrypoint can start embedded worker+NATS.
- Required only when using a standalone external worker service.
- Example: `http://localhost:8081`
### COMPUTE_WORKER_TOKEN
Bearer token for external compute worker auth.
Bearer token for compute-worker auth.
- Required
- Must match worker service `COMPUTE_WORKER_TOKEN`
- Required for standalone external worker service mode.
- Must match worker service `COMPUTE_WORKER_TOKEN`.
- In embedded startup, entrypoint auto-generates one if unset.
### START_EMBEDDED_COMPUTE_WORKER
Controls whether entrypoint auto-starts embedded compute-worker + NATS.
- Default behavior: enabled when `COMPUTE_WORKER_URL` is unset
- Set `false` to disable embedded startup and require external worker URL/token
### EMBEDDED_COMPUTE_WORKER_PORT
Embedded compute-worker HTTP port.
- Default: `8081`
### EMBEDDED_NATS_PORT
Embedded NATS client port.
- Default: `4222`
### EMBEDDED_NATS_MONITOR_PORT
Embedded NATS monitor (`/healthz`) port.
- Default: `8222`
### EMBEDDED_NATS_STORE_DIR
Embedded JetStream storage directory.
- Default: `docstore/nats/jetstream`
### NATS_URL
NATS connection URL used by compute worker runtime.
- Embedded startup default: `nats://127.0.0.1:4222`
- Standalone worker service: set in worker service env (`compute/worker/.env*` or platform env)
### COMPUTE_JOB_CONCURRENCY

View file

@ -47,7 +47,7 @@ title: Stack
Monorepo packages under `compute/`:
- **`@openreader/compute-core`** — ONNX runtime lifecycle, model management, and inference logic shared between local and worker modes
- **`@openreader/compute-core`** — ONNX runtime lifecycle, model management, and inference logic shared by compute worker runtime + app/worker contracts
- ONNX runtime: `onnxruntime-node` with `@huggingface/tokenizers`
- Whisper alignment: `onnx-community/whisper-base_timestamped` (int8) for word-level timestamps
- PDF layout: `Bei0001/PP-DocLayoutV3-ONNX` for document block detection and layout parsing