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.
| Variable | What to set |
|---|---|
APP_ENV | 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 | Production: trace, debug, info, warn, error, fatal, silent. An empty value fails validation in nest-api. |
DATABASE_URL | The same database your API uses — this worker talks to it directly rather than over HTTP, so the schema must match. Production: 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 ( 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 | 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: |
TEMPORAL_ADDRESS | 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_NAMESPACE | 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 | 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 | 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 | 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 withTEMPORAL_TLS_KEY, or startup fails. |
TEMPORAL_TLS_KEY | 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 = use Puppeteer's bundled Chromium. Set this in a slim container image where Chromium is installed separately. Production: Set by the Docker image ( |
Not in .env.example
Section titled “Not in .env.example”| 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 |