Skip to content

Instance Environment

An instance is a docker-compose project. Environment reaches its containers from three different places, owned by three different people — the product author, norsk-ctl itself, and you.

SourceOwnerFor
parameters.yaml${NAME} in the product’s compose.ymlproduct authorConfiguration the product designed: typed, defaulted, shown on the launch form
The generated runner-override.ymlnorsk-ctlWiring the instance needs to work — service addresses, ports, URL prefixes
--overrides filesyouDeployment facts the product cannot know: cloud credentials, proxies, CA bundles

The third is what this page is about.

A product-template parameter is the right home for a value the product shapes — folded into a JSON blob, tied to an allocated port, bounded, given a default and a form label. Adding one means editing the product and releasing it.

Cloud credentials, HTTP_PROXY and NODE_EXTRA_CA_CERTS are not that. The product has no opinion about them, cannot enumerate them, and there may be hundreds. Those are deployment facts, and they belong to whoever is deploying — so they are a launch option, not a product change.

Both are compose files you write and pass at launch. They do different jobs:

  • Sidecars add services that run — new containers with their own lifecycle, ports and health.
  • Overrides adjust the environment of services that already exist. They add no containers.

An override may only set environment and env_file, on a service the stack already declares:

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

--overrides is repeatable, and the paths are stored with the launch config, so instance relaunch keeps them.

Lowest to highest. Nothing at any layer removes a key from a lower one — adding is the only operation, so an override can never accidentally strip the wiring an instance needs.

#LayerNotes
1product compose.ymlenv_file:Within one service, env_file loses to environment
2product compose.ymlenvironment:The product’s own defaults
3runner-override.ymlGenerated by norsk-ctl, including the routing keys
4--overridesenv_file:Per service
5--overridesenvironment:Beats its own env_file, same rule as layers 1–2

Multiple --overrides files apply in command-line order, later wins per key. Override files are merged after any sidecars, so your environment is final.

--param NAME=value does not appear in that table. Parameters are written to the instance’s .env file, which compose uses for interpolation across every file in the project. A parameter reaches a container only where some compose file names the key:

services:
media:
environment:
BUCKET: "${S3_BUCKET}" # interpolated from .env
HTTP_PROXY # bare name, also filled from .env

So --param is how you fill in a ${...} the product (or your sidecar) already declared. --overrides is how you set a variable nobody declared.

Every override file is checked before the launch does anything. A failure names the file, the service and the key:

ErrorCause
OVERRIDE_FILE_NOT_FOUNDThe file does not exist, or could not be read
OVERRIDE_INVALID_YAMLNot YAML, or no top-level services: mapping
OVERRIDE_KEY_NOT_ALLOWEDA key other than environment / env_file under a service, or anything outside services:
OVERRIDE_TAG_NOT_ALLOWEDA !override or !reset tag — these remove values rather than adding them
OVERRIDE_SERVICE_UNKNOWNNo such service in this stack. The message lists the ones there are
ENV_KEY_RESERVEDA variable norsk-ctl owns (below)

These are set by norsk-ctl and the instance’s proxy routing depends on them, so an override naming one refuses the launch rather than quietly breaking the instance:

STUDIO_NORSK_HOST, STUDIO_NORSK_INTERNAL_PREFIX, PORT, STUDIO_WORKING_DIRECTORY, PUBLIC_URL_PREFIX, STUDIO_URL_PREFIX.

LOG_LEVEL is deliberately not reserved. norsk-ctl sets it to info, and overriding it is a supported thing to do.

Anywhere the daemon can read them. Relative paths resolve against the instance’s working directory, absolute paths are taken as-is, and either way the resolved absolute path is what gets stored.

See Set environment variables for worked examples.