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. # Heavy compute is always worker-backed.
# App server calls compute-worker over HTTP for ONNX whisper alignment + PDF layout parsing. # 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 # In single-container self-host setups, run compute-worker + NATS alongside the app and
# point COMPUTE_WORKER_URL at that internal worker endpoint. # point COMPUTE_WORKER_URL at that internal worker endpoint.
# Required: # 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 # Compute worker bind
# Platform note: # Platform note:
# - Local/manual: keep PORT=8081 # - Local/manual: keep PORT=8081

View file

@ -1,7 +1,8 @@
title: Compute Worker (NATS JetStream) 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 ## Overview
@ -30,9 +31,12 @@ Required:
- `S3_SECRET_ACCESS_KEY` - `S3_SECRET_ACCESS_KEY`
> [!IMPORTANT] > [!IMPORTANT]
> **S3 credentials cannot be left blank/empty** when running in worker mode. > This file (`compute/worker/.env*`) is only for standalone worker deployments.
> 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. > In embedded/local startup, app entrypoint spawns worker with the already-resolved root `.env` values.
> 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. > 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: 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. 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 ## Production notes
- Worker mode assumes shared object storage is reachable by both app server and worker. - 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> <details>
<summary><strong>External compute worker dev stack (optional)</strong></summary> <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). Full worker deployment details are in [Compute Worker (NATS JetStream)](./compute-worker).
Start only NATS + compute-worker via compose watch: 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 # 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: Run the main app separately on the host:
@ -145,7 +146,7 @@ Run the main app separately on the host:
pnpm dev pnpm dev
``` ```
For app server worker mode, set: For app -> external worker routing, set in root `.env`:
```env ```env
COMPUTE_WORKER_URL=http://localhost:8081 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). 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> </details>
@ -182,7 +183,15 @@ cp .env.example .env
Then edit `.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 ```env
COMPUTE_WORKER_URL=http://localhost:8081 COMPUTE_WORKER_URL=http://localhost:8081
@ -245,7 +254,7 @@ S3_SECRET_ACCESS_KEY=your-secret-key
``` ```
</TabItem> </TabItem>
<TabItem value="worker-mode" label="External Worker + NATS"> <TabItem value="worker-mode" label="External Worker Service">
```env ```env
API_BASE=http://host.docker.internal:8880/v1 API_BASE=http://host.docker.internal:8880/v1
@ -292,6 +301,9 @@ Learn about migration behavior and commands in [Migrations](../configure/migrati
pnpm dev 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>
<TabItem value="prod" label="Build + Start"> <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 | | `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_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) | | `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_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 | Required bearer token for external compute worker auth | | `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_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_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) | | `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 ### 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` - Example: `http://localhost:8081`
### COMPUTE_WORKER_TOKEN ### COMPUTE_WORKER_TOKEN
Bearer token for external compute worker auth. Bearer token for compute-worker auth.
- Required - Required for standalone external worker service mode.
- Must match worker service `COMPUTE_WORKER_TOKEN` - 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 ### COMPUTE_JOB_CONCURRENCY

View file

@ -47,7 +47,7 @@ title: Stack
Monorepo packages under `compute/`: 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` - ONNX runtime: `onnxruntime-node` with `@huggingface/tokenizers`
- Whisper alignment: `onnx-community/whisper-base_timestamped` (int8) for word-level timestamps - 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 - PDF layout: `Bei0001/PP-DocLayoutV3-ONNX` for document block detection and layout parsing