Skip to content

node-worker environment

Generation copies .env.example to .env. src/config.ts reads it through dotenv; src/instrumentation.ts reads it earlier for the telemetry settings. Variables already set in the environment always win over .env.

VariableWhat to set
APP_ENV
default development

Production: production.

production logs JSON to stdout; anything else pretty-prints when the pretty printer is installed. Stamped on telemetry as deployment.environment.name.
LOG_LEVEL
default debug

Production: info.

pino levels: trace, debug, info, warn, error, fatal, silent. An empty value fails validation in nest-api.
DATABASE_URL
default postgresql://root:postgres@localhost:5432/main

The same database your API uses — this worker talks to it directly rather than over HTTP, so the schema must match.

Production: postgresql://<user>:<password>@<host>:5432/<db>?sslmode=require.

Where to get it: Your PostgreSQL provider.

A worker's value must be the API's database. URL-encode special characters in the password. See PostgreSQL.
REDIS_HOST
default localhost

The same Redis your API produces jobs to. A mismatch here is silent: the worker connects fine and simply never receives anything.

Production: Your Redis host; identical on the API and every worker.

A worker on a different Redis connects fine and never receives a job. See Redis.
REDIS_PORT
default 6379

The same Redis your API produces jobs to. A mismatch here is silent: the worker connects fine and simply never receives anything.

Production: Your Redis port (6379).

REDIS_USER
empty by default

The same Redis your API produces jobs to. A mismatch here is silent: the worker connects fine and simply never receives anything.

Production: An ACL user, if your Redis uses them.

REDIS_PASSWORD
empty by default

The same Redis your API produces jobs to. A mismatch here is silent: the worker connects fine and simply never receives anything.

Production: The Redis password.

OPENOBSERVE_URL
default https://o2.aurostack.co
feature telemetry

OpenTelemetry → OpenObserve: traces, logs and metrics. Leave empty and telemetry stays off. Per project: OPENOBSERVE_ORG is the organization identifier, OPENOBSERVE_TOKEN its ingestion token (IAM → Ingestion Tokens). Any other OTLP backend: set OTEL_EXPORTER_OTLP_ENDPOINT/HEADERS instead.

Production: Your OpenObserve instance.

Telemetry is on only when the URL, org and token are all set. See OpenObserve.
OPENOBSERVE_ORG
empty by default
feature telemetry

OpenTelemetry → OpenObserve: traces, logs and metrics. Leave empty and telemetry stays off. Per project: OPENOBSERVE_ORG is the organization identifier, OPENOBSERVE_TOKEN its ingestion token (IAM → Ingestion Tokens). Any other OTLP backend: set OTEL_EXPORTER_OTLP_ENDPOINT/HEADERS instead.

Production: The project's organization identifier.

Where to get it: OpenObserve → organization settings (or the org segment of its URLs).

OPENOBSERVE_TOKEN
empty by default
feature telemetry

OpenTelemetry → OpenObserve: traces, logs and metrics. Leave empty and telemetry stays off. Per project: OPENOBSERVE_ORG is the organization identifier, OPENOBSERVE_TOKEN its ingestion token (IAM → Ingestion Tokens). Any other OTLP backend: set OTEL_EXPORTER_OTLP_ENDPOINT/HEADERS instead.

Production: The organization's ingestion token (o2oi_…).

Where to get it: OpenObserve → IAM → Ingestion Tokens.

Write-only, but secret: never use it in a browser app (front ends use a RUM token).
OTEL_SERVICE_NAME
default collector
feature telemetry

OpenTelemetry → OpenObserve: traces, logs and metrics. Leave empty and telemetry stays off. Per project: OPENOBSERVE_ORG is the organization identifier, OPENOBSERVE_TOKEN its ingestion token (IAM → Ingestion Tokens). Any other OTLP backend: set OTEL_EXPORTER_OTLP_ENDPOINT/HEADERS instead.

Production: A distinct name per service: shop-api, shop-worker, shop-py.

The service name on every span, and the default stream name, so each service gets its own stream.
TEMPORAL_ADDRESS
default localhost:7233
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line.

Production: Your Temporal frontend, e.g. temporal-grpc.example.com:7233.

See Temporal.
TEMPORAL_NAMESPACE
default default
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line.

Production: The project's namespace, the same on the API and its workers.

TEMPORAL_TASK_QUEUE
default main
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line. The queue this worker polls; must match where the API starts workflows (its TEMPORAL_TASK_QUEUE). A mismatch is silent: workflows just sit waiting.

Production: The queue a worker polls.

API: where workflows are started. Worker: the queue it polls. A mismatch is silent: workflows wait forever.
TEMPORAL_TLS_CA
empty by default
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line. The queue this worker polls; must match where the API starts workflows (its TEMPORAL_TASK_QUEUE). A mismatch is silent: workflows just sit waiting.

Production: The CA that signed the server's certificate, as PEM; empty if it's publicly trusted.

Escaped \n are accepted, so it fits on one line.
TEMPORAL_TLS_CERT
empty by default
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line. The queue this worker polls; must match where the API starts workflows (its TEMPORAL_TASK_QUEUE). A mismatch is silent: workflows just sit waiting.

Production: The project's client certificate, as PEM.

Where to get it: Issued by whoever runs your Temporal (the gateway's CA).

Set it together with TEMPORAL_TLS_KEY, or startup fails.
TEMPORAL_TLS_KEY
empty by default
feature temporal

Temporal: this process also runs the workflows in src/temporal. Locally, the API's dev server (its compose.yml; UI on http://localhost:8233), no TLS. In production, the server address, the project's namespace and its mTLS client certificate (plus the CA that signed the server's), as PEM. Escaped \n are accepted, so each fits on one line. The queue this worker polls; must match where the API starts workflows (its TEMPORAL_TASK_QUEUE). A mismatch is silent: workflows just sit waiting.

Production: The client certificate's private key, as PEM.

A secret: keep it in your secret store.
PUPPETEER_EXECUTABLE_PATH
empty by default
feature browser

Empty = use Puppeteer's bundled Chromium. Set this in a slim container image where Chromium is installed separately.

Production: Set by the Docker image (/usr/bin/chromium or /usr/bin/chromium-browser).

Empty uses Puppeteer's own Chromium, which the image doesn't download.
Variable Used by Effect
OPENOBSERVE_STREAM telemetry Stream name in OpenObserve; defaults to OTEL_SERVICE_NAME
OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS telemetry Send to any OTLP backend instead of OpenObserve; takes precedence
OTEL_SDK_DISABLED=true telemetry Turns telemetry off even when connected
OTEL_METRIC_EXPORT_INTERVAL telemetry Metrics export interval in ms (default 60000)
INFISICAL_PROJECT_ID, INFISICAL_PATH yarn secrets See Secrets with Infisical