Skip to content

CLI Reference

norsk-ctl <command> [options]
First time? Run:
norsk-ctl init guided setup wizard
Commands:
norsk-ctl get <resource> Get resources (hardware, status, prerequisites)
norsk-ctl instance <subcommand> Manage Norsk Studio instances
norsk-ctl domain <subcommand> Inspect Norsk Domains: the shared norskd daemons instances join
norsk-ctl orphaned-dirs <subcommand> Inspect working directories left on disk after terminate
norsk-ctl sideload <subcommand> Inspect the GPU sideload bundle cache
norsk-ctl product <subcommand> Manage Norsk vertical product registrations
norsk-ctl template <subcommand> Manage stored product templates
norsk-ctl config <subcommand> Manage CLI configuration
norsk-ctl serve Start the norsk-ctl daemon in the foreground
norsk-ctl shutdown Shut down norsk-ctl: stop proxy, remove instances, exit daemon
norsk-ctl restart Restart the daemon process (picks up new group membership, e.g. after joining the docker group)
norsk-ctl proxy <subcommand> Manage the nginx reverse proxy
norsk-ctl inspect Show a human-readable dump of the norsk-ctl database
norsk-ctl init Initialize norsk-ctl configuration
norsk-ctl fetch <target> Fetch bundled tools (mkcert)
norsk-ctl source <subcommand> Manage sample SRT sources for instances
norsk-ctl stats Show Docker container resource usage
norsk-ctl upgrade Download a newer norsk-ctl binary and atomically swap it in
norsk-ctl user <subcommand> Manage basic-auth proxy users
norsk-ctl workload <subcommand> Manage workload principals' platform roles
norsk-ctl worker Run as a Norsk Manager worker (operate under Manager control over gRPC)
norsk-ctl scaffold-capabilities Probe this host's DeckLink devices and emit a worker capabilities file to edit
norsk-ctl capabilities Print the daemon and product capabilities this norsk-ctl knows, as JSON
norsk-ctl mcp Run the norsk-ctl MCP stdio adapter (bridges stdio to the daemon's HTTP MCP endpoint)
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl get <resource>
Get resources (hardware, status, prerequisites)
Positionals:
resource Resource type: hardware | status | prerequisites [string] [required] [choices: "hardware", "status", "prerequisites"]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance <subcommand>
Manage Norsk Studio instances
Commands:
norsk-ctl instance delete <id> Delete an instance
norsk-ctl instance describe <id> Describe an instance
norsk-ctl instance restart <id> Restart an instance (fast, no image change)
norsk-ctl instance stop <id> Stop an instance's containers (resumable, not removed)
norsk-ctl instance start <id> Start a stopped instance (resume its containers)
norsk-ctl instance relaunch <id> Relaunch an instance (teardown + recreate)
norsk-ctl instance list List all instances
norsk-ctl instance exists <id> Exit 0 if the instance exists, 1 if not (quiet — for scripts)
norsk-ctl instance launch-template <id> Launch an instance from a stored product template
norsk-ctl instance export-template <name> Export a stored product template as a portable compose bundle with its HANDOVER.md, without launching
norsk-ctl instance delete <id>
Delete an instance
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--purge Also delete the working directory (only if norsk-ctl created it and it clears the safety guard) [boolean] [default: false]
norsk-ctl instance describe <id>
Describe an instance
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance restart <id>
Restart an instance (fast, no image change)
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance stop <id>
Stop an instance's containers (resumable, not removed)
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance start <id>
Start a stopped instance (resume its containers)
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance relaunch <id>
Relaunch an instance (teardown + recreate)
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--host-ports Replace the managed host-port bindings. Each targets a compose
service (omitted = media). Applied on the recreate, so a relaunch
rebinds host ports without a separate delete + launch (repeat the
flag for multiple).
[array]
norsk-ctl instance list
List all instances
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance exists <id>
Exit 0 if the instance exists, 1 if not (quiet — for scripts)
Positionals:
id Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl instance launch-template <id>
Launch an instance from a stored product template
Positionals:
id, instanceId Instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--template, --productTemplateName Name of the stored product template to launch [string] [required]
--param, --paramOverrides Parameter override as KEY=VALUE; repeat for multiple [array]
--working-directory Absolute host path to bind-mount as /data in the instance
containers. Optional; if omitted the runner uses
`~/norsk-runtime/<productName>/<id>/`. Validated at launch
against the product manifest's
`runtime.sharedWorkingDirectory` flag — if false (the
default), refused when another live instance already claims
the same path.
[string]
--cpu-count [number]
--cpu-pinning [array]
--container-user [string]
--network-mode docker (default) or hybrid (media on the host network). Full host mode is not supported for products (studio would collide on its port across instances), so it is not offered. [string] [choices: "docker", "hybrid"]
--memory-limit [string]
--restart-policy [string] [choices: "unless-stopped", "always", "on-failure", "no"]
--restart-max-retries How many times Docker retries a failed container before giving up, i.e.
docker's `on-failure:N` form. Only meaningful with restartPolicy `on-failure`
— the other policies have no retry budget to spend. Left unset, `on-failure`
retries without limit, which is the historical behaviour.
[number]
--open-file-limit Maximum open file descriptors per container (docker `ulimits.nofile`, soft
and hard alike), applied to every service in the instance. Defaults to 65535.
Left unset a container inherits the host daemon's limit, which on some hosts is
low enough for a busy media graph to crash with EMFILE.
[number]
--shm-size Size of media's private /dev/shm (docker shm_size syntax, e.g. "8gb").
Defaults to the product's own shm_size, else 2gb. Private to this instance
(ADR-0011), except on the quadra hardware profile: the NETINT driver keeps
its card resource table in a /dev/shm shared with the host, so there the
host's /dev/shm is mounted over media's and this size does not govern.
[string]
--shared-memory Host tmpfs mounts shared into media. Each entry is an absolute host path
to a tmpfs the OPERATOR created (e.g. an MXL domain), bind-mounted into the
media container at the same path. Repeatable — an instance bridging two
domains mounts both, without those domains seeing each other. Validated at
launch: each path must exist, be tmpfs, and be world-writable, refused
loudly otherwise. An empty list explicitly declines a product-template
declared default.
[array]
--domain The Norsk Domain this instance joins. Members of a domain share ONE norskd
memory daemon (a dedicated container), so their engines adopt each other's
buffers zero-copy over the norsk-link. Absent (or "") = isolated: the engine
self-spawns its own norskd. Orthogonal to discovery (which stays cross-fleet).
[string]
--st2110-nics ST 2110 NICs (by interface name) this instance claims for MTL: the media
container gets host networking, the ST 2110 capabilities, each NIC's RDMA
device and its /dev/hugepages-st2110-<ifname> mount. A NIC is held by one
instance at a time. An empty list declines a product-template default.
[array]
--host-ports Managed host-port bindings. Each targets a compose service (omitted =
media) and is published in docker mode; hybrid exposes media's via the
host network directly. Non-media targets are persisted and validated
but not yet emitted into the override.
[array]
--public-host Per-instance External URL override for advertised links
(runtime-screen hrefs, the runner base URL handed to the
product). Full URL with scheme, validated like the
daemon-wide setting; the oauth2 proxy itself stays on the
global External URL.
[string]
--hardware Accelerator to reserve on media — GPU (nvidia) or Netint Quadra; none = no reservation. quadra maps every NETINT NVMe device the host carries and mounts the host /dev/shm over media's private one (the driver's resource table lives there); the launch is refused if no card is found. [string] [choices: "none", "nvidia", "quadra"]
--internal-only Launch the instance binding NO host ports — every service's compose
`ports:` mapping is stripped, so studio/media/ingest/egress are reachable
only over the daemon's norsk-net bridge (by `<id>-<service>-1` service DNS).
For callers that reach the instance over that network (e.g. a co-located
test harness) and want to avoid host-port collisions between concurrent
instances. Default false = publish as the product template declares.
[boolean]
--publish-debug-ports Publish the `studio` service's host ports (Studio's editor and API) on
every host interface instead of 127.0.0.1. Default false: ctl gives each
such compose `ports:` entry an explicit loopback bind, because docker
publishes an unbound port on 0.0.0.0 and inserts its rules ahead of host
firewalls like ufw. Only `studio` is rebound — every other service's
published ports are left exactly as the product wrote them. Even on
`studio`, a UDP mapping, a host side naming a declared allocatedPorts
parameter, and an entry already carrying a bind IP are all left alone.
Reach Studio through the ingress on 443 instead; set this only for a host
where the LAN is trusted and a direct `http://<host>:<port>` is wanted.
[boolean]
--sidecars Operator-supplied compose files (paths relative to the working
directory) merged after the override — extra services alongside the
product. Project-name isolation namespaces their containers.
[array]
--overrides, --composeOverrides Operator environment overrides: compose files that adjust the
environment of services the stack already defines (paths relative to
the working directory). Merged after the sidecars, so operator
environment is final.
Distinct from `sidecars`, which adds services that RUN. Each file is
validated down to `services.<name>.{environment,env_file}` — any other
key, a `!override`/`!reset` tag, an unknown service, or a key the
runner owns (STUDIO_NORSK_HOST, PORT, PUBLIC_URL_PREFIX,
STUDIO_URL_PREFIX, STUDIO_NORSK_INTERNAL_PREFIX,
STUDIO_WORKING_DIRECTORY) refuses the launch.
[array]
--launch-key, --launchKey Caller-minted id for this launch attempt. A launch is held open for the whole image pull and compose up, so a caller can lose the response without losing the work (a severed connection, a proxy reload). Re-sending the same request with the same key is that same launch asking again: it answers with the instance the first attempt created instead of refusing with ID_CONFLICT. Mint one key per launch attempt and reuse it across retries. Omit it to keep the plain refusal. [string]
--launch-as, --launchAs PassRole: the platform role the launched instance's own workload principal (`urn:norsk:workload:instance:<id>`) holds on `instance/<id>`, and nowhere else. The caller may pass only a role it holds itself (on top of being allowed to launch); anything more is refused 403 with code `role_escalation` in every enforcement mode. `admin` is never accepted, whoever the caller is: no workload may hold it, so it is refused 403 with code `workload_admin_launch` in every enforcement mode, and nothing is launched. Omit it and the new instance's workload holds nothing. [string] [choices: "viewer", "operator", "builder", "admin"]
--on-behalf-of, --onBehalfOf Free text naming who asked the caller to launch (a workload acting for an operator's click, say). Recorded in the audit log beside the launch and trusted for NOTHING: the decision is always the authenticated caller's, whatever this says. [string]
norsk-ctl instance export-template <name>
Export a stored product template as a portable compose bundle with its HANDOVER.md, without launching
Positionals:
name Product template name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--to Absolute path on the daemon's host to materialise (created/cleared) [string] [required]
--include-license Copy the real licence into the bundle instead of writing a placeholder [boolean] [default: false]
--param Product-template parameter override: NAME=value (repeatable) [array] [default: []]
--project-name Compose project name in the bundle (defaults to the sanitised template name) [string]
--format What to print: the export result (compose), or the bundle's HANDOVER.md (handover) [string] [choices: "compose", "handover"] [default: "compose"]
norsk-ctl domain <subcommand>
Inspect Norsk Domains: the shared norskd daemons instances join
Commands:
norsk-ctl domain list List Norsk Domains with their daemon and members
norsk-ctl domain describe <name> Describe a Norsk Domain
norsk-ctl domain set <name> Declare a Norsk Domain's hugepage pool (applied when its daemon is next created)
norsk-ctl domain clear <name> Forget a Norsk Domain's settings
norsk-ctl domain list
List Norsk Domains with their daemon and members
Options:
-o, --output Dump raw entries instead of the default table [string] [choices: "yaml", "json"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl domain describe <name>
Describe a Norsk Domain
Positionals:
name Domain name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl domain set <name>
Declare a Norsk Domain's hugepage pool (applied when its daemon is next created)
Positionals:
name Domain name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--hugepages Pool size, e.g. "4g" or "512m", or "none" for no hugepages [string] [required]
--numa-node NUMA node to bind the pool to (the ST 2110 NIC's) [number]
norsk-ctl domain clear <name>
Forget a Norsk Domain's settings
Positionals:
name Domain name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl orphaned-dirs <subcommand>
Inspect working directories left on disk after terminate
Commands:
norsk-ctl orphaned-dirs list List orphaned working directories
norsk-ctl orphaned-dirs clear <id> Forget an orphan entry (leaves the directory on disk)
norsk-ctl orphaned-dirs list
List orphaned working directories
Options:
-o, --output Dump raw entries instead of the default table [string] [choices: "yaml", "json"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl orphaned-dirs clear <id>
Forget an orphan entry (leaves the directory on disk)
Positionals:
id Orphan instance ID [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl sideload <subcommand>
Inspect the GPU sideload bundle cache
Commands:
norsk-ctl sideload status List the CUDA sideload bundles fetched into the local cache
norsk-ctl sideload fetch Fetch CUDA sideload bundles into the cache ahead of a launch
norsk-ctl sideload status
List the CUDA sideload bundles fetched into the local cache
Options:
-o, --output Dump raw entries instead of the default table [string] [choices: "yaml", "json"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl sideload fetch
Fetch CUDA sideload bundles into the cache ahead of a launch
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--product Registered product whose media image to fetch bundles for [string]
--image Media image ref to fetch bundles for. Needs nothing pulled, so a builder can seed a cache for a host it is not. [string]
--bundle Which bundles to fetch. Default: gpu-video, plus gpu-inference when --product declares it. Never inferred from this host having a GPU. [array]
--cache-dir Fetch locally into this directory instead of through the daemon. For baking an image with no daemon running; requires --image. Deliberately has no default — the daemon owns its cache. [string]
norsk-ctl product <subcommand>
Manage Norsk vertical product registrations
Commands:
norsk-ctl product add Register product(s) from a license file, or a container image / dev URL
norsk-ctl product list List registered products
norsk-ctl product exists <name> Exit 0 if the product is registered, 1 if not (quiet — for scripts)
norsk-ctl product remove <name> Unregister a product (and stop its container if any)
norsk-ctl product reload <name> Pull the image, re-run the control plane and refresh its not-in-use default templates (run after a rebuild); dev products re-read the manifest only
norsk-ctl product pull <name> Prefetch the product's images (renders its default product template and docker compose pulls them)
norsk-ctl product add
Register product(s) from a license file, or a container image / dev URL
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--license-file BYOL license file. Registers every product it entitles, pulling each product's image (repo from the license, tag derived from the version constraint or --tag). [string]
--product With --license-file: register only this product instead of all entitled products [string]
--tag With --license-file: image tag to pull (overrides the tag derived from the version constraint) [string]
--image Explicit container image to run (overrides the image derived from the license) [string]
--dev-url URL of an already-running localhost dev server (e.g. http://localhost:4321). License optional. [string]
--env Deploy-time environment for the product's control-plane container, KEY=VALUE (repeatable, e.g. --env FUNKE_HARDWARE=software). Container adds only; ignored with --dev-url. [array]
--marketplace-provider Marketplace provider for this product's license (instead of --license-file) [string] [choices: "aws", "gcp"]
norsk-ctl product list
List registered products
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl product exists <name>
Exit 0 if the product is registered, 1 if not (quiet — for scripts)
Positionals:
name Product name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl product remove <name>
Unregister a product (and stop its container if any)
Positionals:
name Product name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl product reload <name>
Pull the image, re-run the control plane and refresh its not-in-use default templates (run after a rebuild); dev products re-read the manifest only
Positionals:
name Product name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl product pull <name>
Prefetch the product's images (renders its default product template and docker compose pulls them)
Positionals:
name Product name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--sideload Also fetch the product's CUDA sideload bundles. Opt-in — having a GPU is not consent to use it, so ctl never assumes. [boolean] [default: false]
--dry-run Report what would be pulled, including the media image ref `sideload fetch --image` takes, without downloading anything. [boolean] [default: false]
norsk-ctl template <subcommand>
Manage stored product templates
Commands:
norsk-ctl template list List stored product templates
norsk-ctl template show <name> Show a stored product template's metadata
norsk-ctl template default <product> Print the default (examples) product template name for a product (for scripts)
norsk-ctl template import <file> Import a product template from a tar file
norsk-ctl template build <name> Build and store a product template from a product's own inputs (JSON)
norsk-ctl template refresh <name> Re-fetch a stored product template's snapshot from its originating product
norsk-ctl template remove <name> Remove a stored product template
norsk-ctl template list
List stored product templates
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl template show <name>
Show a stored product template's metadata
Positionals:
name Product template name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl template default <product>
Print the default (examples) product template name for a product (for scripts)
Positionals:
product Product name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl template import <file>
Import a product template from a tar file
Positionals:
file Path to a product template tar file [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--name Name to register the product template under (lowercase letters, digits, hyphens) [string] [required]
norsk-ctl template build <name>
Build and store a product template from a product's own inputs (JSON)
Positionals:
name Name to register the built product template under [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--product Registered product name to build from [string] [required]
--input Path to a JSON file of the product's template inputs [string] [required]
--replace Overwrite an existing product template of this name (refused while an instance uses it) [boolean] [default: false]
norsk-ctl template refresh <name>
Re-fetch a stored product template's snapshot from its originating product
Positionals:
name Product template name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl template remove <name>
Remove a stored product template
Positionals:
name Product template name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl config <subcommand>
Manage CLI configuration
Commands:
norsk-ctl config set Update config values
norsk-ctl config show Show current config
norsk-ctl config set
Update config values
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--working-directory Working directory root; each instance gets a <root>/<product>/<instance> subdirectory [string]
--public-host Public host clients use to reach this server (bare host, e.g. arnuc or my.server.com) [string]
--proxy-port Host port the proxy listens on, overriding the network-mode default (e.g. 443 in Docker mode) [number]
--external-port Port clients reach this host on when another reverse proxy fronts it (e.g. 443 while --proxy-port is 8443). Advertised URLs name this port [number]
--upgrade-check Enable/disable the periodic upgrade check (off = no S3 lookup, no UI banner) [string] [choices: "on", "off"]
--spectrum-cache Share one Spectrum compile cache on this host across media engines (off = each engine compiles from empty, nothing kept on the host) [string] [choices: "on", "off"]
--smt-policy How --cpu-count hands out hyperthread siblings: pairs = whole physical cores (default), primary-only = one thread per core, sibling left idle [string] [choices: "pairs", "primary-only"]
norsk-ctl config show
Show current config
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl serve
Start the norsk-ctl daemon in the foreground
Options:
--help Show help [boolean]
norsk-ctl shutdown
Shut down norsk-ctl: stop proxy, remove instances, exit daemon
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--daemon-only Only stop the daemon; leave proxy + instances running (e.g. for an in-place binary swap) [boolean] [default: false]
norsk-ctl restart
Restart the daemon process (picks up new group membership, e.g. after joining the docker group)
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy <subcommand>
Manage the nginx reverse proxy
Commands:
norsk-ctl proxy pull Pre-pull nginx and oauth2-proxy images
norsk-ctl proxy start Generate nginx config and start nginx
norsk-ctl proxy stop Stop nginx
norsk-ctl proxy reload Regenerate config and reload nginx without downtime
norsk-ctl proxy status Show nginx process status and active upstreams
norsk-ctl proxy logs View nginx access or error logs
norsk-ctl proxy pull
Pre-pull nginx and oauth2-proxy images
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy start
Generate nginx config and start nginx
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy stop
Stop nginx
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy reload
Regenerate config and reload nginx without downtime
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy status
Show nginx process status and active upstreams
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl proxy logs
View nginx access or error logs
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--type Log type to view [string] [choices: "access", "error"] [default: "access"]
-n, --lines Number of tail lines to show [number] [default: 100]
-f, --follow Poll for new log output every 2s [boolean] [default: false]
norsk-ctl inspect
Show a human-readable dump of the norsk-ctl database
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl init
Initialize norsk-ctl configuration
Options:
--help Show help [boolean]
--cert-path Path to TLS certificate file (PEM) [string]
--key-path Path to TLS private key file (PEM) [string]
--cert-source Certificate source type [string] [choices: "mkcert", "self-signed", "user", "certbot"]
--proxy-auth Local auth on the proxy. 'none' skips auth entirely (network-restricted workers only); 'manager' verifies the Manager's session on every request and redirects sign-in to the Manager (requires --manager-base) [string] [choices: "oauth", "none", "manager"]
--manager-base Operator-facing Manager base URL (https://<fqdn>); required with --proxy-auth manager [string]
--manager-verify-base VPC-internal URL for auth verification (defaults to --manager-base; needed when security groups only admit private-side traffic) [string]
--working-directory Working directory root; each instance gets a <root>/<product>/<instance> subdirectory [string]
--proxy-user Create a proxy basic-auth user [string]
--proxy-password Password for --proxy-user [string]
--network-mode Default network mode for new instances: docker (bridge+proxy), hybrid (studio proxied, media on host) [string] [choices: "docker", "hybrid"]
--public-host Public host clients use to reach this server (bare host or host:port; scheme stripped) [string]
--advertise 'none' declares this host has no operator-reachable address (Manager-provisioned worker on an unrouted VPC): launches omit the advertised preview/media base URL and mark instances so UIs can say so. Mutually exclusive with --public-host [string] [choices: "none"]
--proxy-port Host port the proxy listens on, overriding the network-mode default (lets Docker mode serve on 443). 0 lets docker assign it [number]
--external-port Port clients reach this host on when another reverse proxy fronts it (e.g. 443 while --proxy-port is 8443). Advertised URLs name this port instead of the bound one [number]
--marketplace Set the base license type to marketplace (default byol). Marketplace locks the daemon to marketplace licensing: products may not use a BYOL license, and at most one instance may exist at a time. Provider defaults to gcp; override with --marketplace-provider. [boolean] [default: false]
--marketplace-provider Marketplace cloud provider (implies --marketplace). Taken at face value — Norsk Media validates the entitlement at runtime. Defaults to gcp when --marketplace is set without it. (aws to follow.) [string] [choices: "gcp"]
--force Overwrite existing config.yaml [boolean] [default: false]
--http-redirect Bind a port for HTTP→HTTPS redirect (and certbot HTTP-01). Default true, on port 80. Pass --no-http-redirect when 80 is owned by something else and no redirect is wanted, or --http-redirect-port to move it. [boolean] [default: true]
--http-redirect-port Host port for the HTTP→HTTPS redirect listener (default 80). Ignored with --no-http-redirect. certbot HTTP-01 issuance needs the default [number]
--start-server Start `norsk-ctl serve` immediately after init succeeds (use --no-start-server to opt out) [boolean]
norsk-ctl fetch <target>
Fetch bundled tools (mkcert)
Commands:
norsk-ctl fetch mkcert Download mkcert v1.4.4 to the state directory's bin/
norsk-ctl fetch mkcert
Download mkcert v1.4.4 to the state directory's bin/
Options:
--help Show help [boolean]
norsk-ctl source <subcommand>
Manage sample SRT sources for instances
Commands:
norsk-ctl source start <instanceId> [preset] Start a sample source streaming to an instance
norsk-ctl source stop <instanceId> <name> Stop a sample source
norsk-ctl source list List running sample sources
norsk-ctl source presets List available source presets
norsk-ctl source start <instanceId> [preset]
Start a sample source streaming to an instance
Positionals:
instanceId Target instance ID [string] [required]
preset Built-in source preset (camera1, camera2). Exactly one of `preset`, `mediaFile` or `generate` selects the asset; omitting all three is the same as naming none. [string]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port SRT target port (default: 5001) [number]
--help Show help [boolean]
--media-file Absolute path on the DAEMON's host to a media file to stream instead of a preset. Its directory is bind-mounted read-only into the source container; the file is never copied or uploaded. [string]
--generate Stream a generated pattern instead of a file — `bars` (SMPTE bars + tone) or `testsrc` (moving pattern with a burnt-in timestamp). Nothing is downloaded: the pattern is rendered once into the sample-media cache on first use (a few seconds) and thereafter looped by copy, so it costs a running source no more CPU than a preset does. [string] [choices: "bars", "testsrc"]
--resolution Frame size for a generated pattern as `WIDTHxHEIGHT` (default: 1280x720). Both dimensions must be even, which is what the h.264 yuv420p encoding requires. Generated sources only — a file streams at whatever size it was encoded at. [string]
--frame-rate Frame rate for a generated pattern (default: 25). Whole (`50`), decimal (`29.97`) or exact broadcast rational (`30000/1001`). Generated sources only — a file streams at whatever rate it was encoded at. [string]
--sample-rate Audio sample rate in Hz for a generated pattern (default: 48000). Must be one AAC supports. Generated sources only. [number]
--protocol How the source publishes (default: srt). SRT carries the stream's identity as a `streamid` option; RTMP carries the same `streamId` value as its `<app>/<key>` path. [string] [choices: "srt", "rtmp"]
--service Compose service hosting the listener (default: media). Take it from the instance's `ingestPorts`; a source dials the service directly inside the instance's network, so a sidecar listener is reached without any host binding. [string]
--passphrase SRT encryption passphrase, 10-79 characters. SRT only — sending it with `protocol: rtmp` is refused rather than ignored. It reaches the source container in its ffmpeg command line, so anyone who can inspect the container can read it; use it to match a listener's configuration, not to keep a secret from the host. [string]
--latency SRT receiver latency in milliseconds. SRT only; the libsrt default applies when unset. [number]
--stream-id Identity the source claims at the destination (default: the source name). SRT sends it as `streamid`; RTMP uses it as the `<app>/<key>` path. Override when the target listener restricts what it accepts. [string]
--name Override the source identity (container name + management key). Defaults to the preset, the generated pattern, or the media file's stem. Set when one instance needs to run several sources from the same asset — `name` must be unique within an instance. [string]
norsk-ctl source stop <instanceId> <name>
Stop a sample source
Positionals:
instanceId Instance ID [string] [required]
name Source name [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl source list
List running sample sources
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--instance Filter by instance ID [string]
norsk-ctl source presets
List available source presets
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl stats
Show Docker container resource usage
Options:
-o, --output, --output Output format [string] [choices: "yaml", "json", "table", "yaml", "json"] [default: "table"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl upgrade
Download a newer norsk-ctl binary and atomically swap it in
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
--version Pin to a specific version (overrides --channel) [string]
--channel Channel to track when --version is not given [string] [choices: "nightly", "rc", "latest", "stable", "beta"] [default: "latest"]
--list Show available channels + recent versions without upgrading [boolean] [default: false]
--dry-run Resolve target version + verify checksum but do not swap binaries [boolean] [default: false]
--max-versions How many versions to show with --list (default 10) [number] [default: 10]
norsk-ctl user <subcommand>
Manage basic-auth proxy users
Commands:
norsk-ctl user set <name> Add or update a basic-auth user
norsk-ctl user delete <name> Remove a basic-auth user
norsk-ctl user list List basic-auth users
norsk-ctl user role <name> <role> Set a user's platform role
norsk-ctl user set <name>
Add or update a basic-auth user
Positionals:
name Username [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
-p, --password Password (if omitted, read from stdin) [string]
--role Platform role for a NEW user (ignored when the user already exists) [string] [choices: "viewer", "operator", "builder", "admin"]
norsk-ctl user delete <name>
Remove a basic-auth user
Positionals:
name Username [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl user list
List basic-auth users
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl user role <name> <role>
Set a user's platform role
Positionals:
name Username [string] [required]
role [string] [required] [choices: "viewer", "operator", "builder", "admin"]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl workload <subcommand>
Manage workload principals' platform roles
Commands:
norsk-ctl workload role <workload> <role> Set a workload's platform role on the host
norsk-ctl workload clear <workload> Clear a workload's platform role on the host
norsk-ctl workload role <workload> <role>
Set a workload's platform role on the host
Positionals:
workload An instance id, or a full workload urn (urn:norsk:workload:...) [string] [required]
role [string] [required] [choices: "viewer", "operator", "builder", "admin"]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl workload clear <workload>
Clear a workload's platform role on the host
Positionals:
workload An instance id, or a full workload urn (urn:norsk:workload:...) [string] [required]
Options:
-o, --output Output format [string] [choices: "yaml", "json"] [default: "yaml"]
--port Daemon port (default 8333, or $NORSK_CTL_PORT) [number]
--help Show help [boolean]
norsk-ctl worker
Run as a Norsk Manager worker (operate under Manager control over gRPC)
Options:
--help Show help [boolean]
--config-file Path to the worker config JSON written by Manager cloud-init [string] [default: "/mnt/worker.config"]
--bind-address Address the gRPC server listens on (use 0.0.0.0 for all interfaces) [string] [default: "0.0.0.0"]
--enable-ui-in-worker-mode Also start the norsk-ctl UI/Express server (off by default in worker mode) [boolean] [default: false]
--license-output-path Path to write the license file Manager sends in HelloResponse (parent dir created if missing). Default: <state dir>/worker-mode/license.json, beside the worker's other state. [string]
--manager-url Manager gRPC URL for cluster-mode registration (e.g. host:port). When set with --token, replaces --config-file. [string]
--token Local-server join token (paired with --manager-url; from the Manager's Local Servers page). Single-use: the first register exchanges it for a node credential the worker keeps, and later starts need neither flag. Prefer --token-file: an argument shows in the process list. [string]
--token-file Read the join token from this file (one line) instead of --token. [string]
--listen-port Listen port in cluster mode (default: random ephemeral) [number] [default: 0]
--advertise-address Address to tell Manager to dial back on (default: 127.0.0.1; usually you want a real LAN IP) [string] [default: "127.0.0.1"]
--decklink-enum-image Image ref for the DeckLink enumeration container (norsk docker/decklink-enum). Run at startup when a Blackmagic PCI device is present, to advertise each sub-device's stable identity on NodeInventory. Empty string disables the probe. [string] [default: "norskvideo/decklink-enum"]
--capabilities-file Path to a JSON file declaring this worker's capabilities with attributes (operational knowledge no probe can discover, e.g. which DeckLink port carries which feed). Declared entries override same-name probed ones on NodeInventory. [string]
--proxy-url Reverse-proxy URL to advertise to Manager (e.g. https://worker-1.example.com:9443). norsk-mgr uses this to route per-job runtime UIs through this worker. When omitted, the daemon falls back to `https://<advertise-address>:<defaultClusterProxyPort>`. [string]
--job-socket Run the job socket a handover-migratable job connects to (advertised as the `job-socket` capability). --no-job-socket disables it: jobs get no NORSK_WORKER_WS_URL and handover migrations are not placed here. [boolean] [default: true]
--job-socket-port Host port the job socket listens on; containers reach it as ws://host.docker.internal:<port> [number] [default: 6797]
--instance-namespace Prefix for this worker's instance ids (docker-compose project names), `<ns>-<jobId>`. Required when several workers share one Docker daemon — a real deployment shape, not a test aid — so their projects cannot collide when the same job lands on two of them (a migration does exactly that). Persisted under the worker's state dir; omit on a restart to keep the recorded value, pass '' to clear it. [string]
--grpc-tls-dir Serve the worker gRPC service over mutual TLS using ca.pem, cert.pem and key.pem in this directory: only a peer with a certificate signed by ca.pem (the Manager) can connect. The files are re-read as they change. Absent = plaintext. Cloud workers get this from their cloud-init when the deployment is installed with mTLS. [string]
--orphan-terminate-after Seconds without word from the Manager after which this worker terminates its own instance, so a node whose Manager never returns stops billing. EC2 only (needs the instance role's permission to terminate itself); must outlast any Manager outage. Absent or 0 = never. Also read from $NORSK_WORKER_ORPHAN_TERMINATE_AFTER, which is how cloud workers get it from their cloud-init. [number]
--log-config-file A fluent-bit output config (the [OUTPUT] sections saying where logs go). Every media engine this worker launches gets it, and ships its logs with it; the engine's environment carries NORSK_NODE_ID, NORSK_RUNTIME_ID and NORSK_INSTANCE_ID for it to use. Absent = logs stay on the node. Also read from $NORSK_WORKER_LOG_CONFIG_FILE, which is how cloud workers get it when the Manager is given one. [string]
--log-forward host:port of the node's log agent (the log-agent node service, e.g. host.docker.internal:24224). Media engines then forward every log record there instead of being given an output config, so no destination or token reaches an engine container. Wins over --log-config-file. Also read from $NORSK_WORKER_LOG_FORWARD, which is how cloud workers get it when their deployment runs a log agent. [string]
--service-down-grace Seconds a started job's service may stay down (Docker's restarts included) before this worker reports the job failed. Default 120, matching the Manager's own job-startup patience: shorter and a slow-but-healthy restart reads as a failure; longer and a dead job sits active for that much longer. [number] [default: 120]
--instances-root Directory each job's working directory is made under (bind-mounted into its runtime as /data). Default: <state dir>/worker-mode/instances, beside the instance records. Set it where the worker runs in a container sharing the host's Docker socket, to a path mounted identically on both sides — otherwise the host daemon mounts an empty directory and the product finds /data bare. $NORSK_CTL_WORKER_INSTANCES_ROOT predates this flag and is still honoured when the flag is absent. [string]
--image-store-max Bound the engine's image store to at most this many images: least-recently-wanted are removed first, images a container uses and images pulled or seen in use within the last hour never. 0 (the default) leaves the store alone — set it only on an engine that exists for this worker, never on a shared or hand-curated one. [number] [default: 0]
--discovery-token Pre-shared token for the fleet discovery server (task 76). Enables the node's fleet uplink alongside NORSK_CTL_DISCOVERY_ENABLE; falls back to NORSK_DISCOVERY_TOKEN. [string]
--discovery-upstream Explicit fleet discovery address (host:port). When omitted in cluster mode it is derived from --manager-url's host + --discovery-port. [string]
--discovery-port Fleet discovery server port on the manager host (for deriving the upstream from --manager-url). [number] [default: 7001]
--discovery-tls-ca Path to the fleet CA (PEM). When set, the node dials its discovery upstream over TLS (verifying it against this CA); its own local listener stays plaintext (Scope A, client-only TLS). [string]
norsk-ctl scaffold-capabilities
Probe this host's DeckLink devices and emit a worker capabilities file to edit
Options:
--help Show help [boolean]
--output-file Write the capabilities file here (default: stdout) [string]
--decklink-enum-image Image ref for the DeckLink enumeration container (norsk docker/decklink-enum) [string] [default: "norskvideo/decklink-enum"]
norsk-ctl capabilities
Print the daemon and product capabilities this norsk-ctl knows, as JSON
Options:
--help Show help [boolean]
norsk-ctl mcp
Run the norsk-ctl MCP stdio adapter (bridges stdio to the daemon's HTTP MCP endpoint)
Options:
--help Show help [boolean]