Skip to content

Set environment variables

Use --overrides to set environment on the services an instance already runs, without changing the product. For the model behind it — the precedence chain, what is validated — see Instance Environment.

A compose file naming services the stack already has, setting only environment and/or env_file:

/etc/norsk/tls.yml
services:
studio:
environment:
NODE_TLS_REJECT_UNAUTHORIZED: "0"
Terminal window
norsk-ctl instance launch-template monday \
--template new-nightly \
--overrides /etc/norsk/tls.yml

The flag repeats, and later files win per key:

Terminal window
norsk-ctl instance launch-template monday \
--template new-nightly \
--overrides /etc/norsk/base.yml \
--overrides /etc/norsk/monday-only.yml

Keep the secrets in a plain KEY=VALUE file and point env_file at it. norsk-ctl never reads that file — compose passes it straight to the container — so nothing lands in the daemon’s database, in instance describe, or in a command line you might paste into a ticket.

/etc/norsk/aws.env
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=eu-west-1
/etc/norsk/aws.yml
services:
media:
env_file:
- /etc/norsk/aws.env
Terminal window
chmod 600 /etc/norsk/aws.env
norsk-ctl instance launch-template s3-out --template my-product --overrides /etc/norsk/aws.yml

Rotating a credential is then an edit plus norsk-ctl instance relaunch s3-out — the launch config does not change, because it only stores the path.

Each service is named separately, so studio and media can differ — useful when a variable means different things in each:

services:
studio:
environment:
LOG_LEVEL: debug
media:
environment:
LOG_LEVEL: info
HTTP_PROXY: http://proxy.internal:3128
NO_PROXY: localhost,127.0.0.1,media,studio

LOG_LEVEL is set to info by norsk-ctl and is safe to override:

/etc/norsk/debug.yml
services:
studio:
environment:
LOG_LEVEL: debug

Studio compiles its workflow document when the instance starts, and for config fields the component author marked as overridable, an environment variable beats the value saved in the document. So an override can retune a workflow without re-rendering it or building a new product template.

The variable is named <COMPONENT_ID>_<FIELD>, uppercased, with spaces and dashes becoming underscores and other punctuation dropped. The component id is the id in the workflow’s components: entry — so for an SRT listener saved as srt_input:

/etc/norsk/ingest.yml
services:
studio:
environment:
SRT_INPUT_PORT: "6000"
SRT_INPUT_PASSPHRASE: hunter2
Terminal window
norsk-ctl instance launch-template live-01 \
--template srt-hls \
--overrides /etc/norsk/ingest.yml \
--host-ports 6000:6000/udp

Two things to get right:

  • The variable goes on studio, even though it is media that binds the SRT socket. Studio compiles the document; the media container carries out the result.
  • Moving a listener port does not publish it. The port a component listens on inside the stack and the port reachable from outside are separate concerns — --host-ports is what opens the second one. See Network modes.

Settings shared across a whole document work the same way under a GLOBAL_ prefix — GLOBAL_TIME_DOMAINS, for instance.

studio-validate, shipped in the Studio image, prints every overridable field in a document along with its type and help text. Run it against the image your template pins (grep image: ~/.norsk-ctl/product-templates/<template>/compose.yml):

Terminal window
docker run --rm -v /path/to/workflow-dir:/doc:ro \
-e NODE_CONFIG='{"server":{"library":["@norskvideo/norsk-studio-built-ins"]}}' \
<studio-image> npx studio-validate /doc/workflow.yml

The config array in the JSON it prints is the list, and envName is the variable to set:

{
"id": "port",
"envName": "SRT_INPUT_PORT",
"help": "The port this SRT input will listen on",
"value": "number"
}

Give it the same library list the instance runs with — a component from a library that is not loaded contributes no keys.

The certificate itself needs to be inside the container, which is a mount — so this one is a sidecar for the mount plus an override for the variable, or a single sidecar doing both:

/etc/norsk/ca.yml (sidecar — it mounts a file)
services:
studio:
volumes:
- /etc/norsk/corp-ca.pem:/etc/ssl/certs/corp-ca.pem:ro
/etc/norsk/ca-env.yml (override — it sets a variable)
services:
studio:
environment:
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/corp-ca.pem
Terminal window
norsk-ctl instance launch-template monday --template new-nightly \
--sidecars /etc/norsk/ca.yml \
--overrides /etc/norsk/ca-env.yml

Overrides can target a service a sidecar introduced, since it is part of the same project:

connector.yml (sidecar)
services:
connector:
image: my-org/connector:1.0.0
depends_on:
studio:
condition: service_healthy
connector-env.yml (override)
services:
connector:
environment:
TARGET_URL: https://example.internal/ingest

Errors arrive before anything is launched, and name the file:

/etc/norsk/bad.yml: 'volumes' is not allowed under service 'studio' — an override may
only set environment and env_file. Use --sidecars for anything else.
/etc/norsk/evil.yml: 'PUBLIC_URL_PREFIX' on service 'studio' is set by norsk-ctl and
the instance's routing depends on it
/etc/norsk/typo.yml: no service 'studioo' in this stack (services: studio, media)

The full list of checks is in Instance Environment → Validation.

norsk-ctl renders the whole file chain — product compose, runner override, sidecars, your overrides — through docker compose config. That is the merged result, with env_file values resolved, so it answers “did my override apply?” directly. Use the Copy Compose config button on the instance page, or:

Terminal window
curl -s -H "x-norsk-proxy: $(cat ~/.norsk-ctl/proxy-secret)" \
http://localhost:8333/api/v1/product-instances/my-instance/compose

If a variable you set is not in there, check the precedence table and that you named the right service.

For the rarer question of what a running container actually holds — including variables baked into the image — docker inspect --format '{{json .Config.Env}}' on <instance-id>-<service>-1 is the authority.

Filling in a variable the product already declared

Section titled “Filling in a variable the product already declared”

If the product’s compose.yml references ${SOMETHING}, that is a parameter, not an override — use --param:

Terminal window
norsk-ctl instance launch-template monday --template new-nightly --param SRT_ADDR=srt://1.2.3.4:9999

norsk-ctl template show <name> lists the parameters a template declares.