Skip to content

Quickstart

norsk-ctl is the control plane: it runs the containers, the reverse proxy, and the config, and it is what you install first. Products — Norsk Studio, Norsk Probe, Norsk Playout, Norsk Remote Commentary — are a separate second step you add to a running norsk-ctl, and you can add more than one.

So this page follows that order: install the platform, add a product, launch something on it.

One command. Run it with nothing after it and it asks for what it needs — this machine or a server, your license file, an admin password, and the address clients will use — then shows you the plan and waits for a yes:

Terminal window
curl -fsSL https://norsk.video/install/ctl | bash

No sudo on that line. Pick “server” and it asks for your password when it reaches the steps that need root; pick “local” and it never needs one.

When it finishes norsk-ctl is installed and configured (the installer hands off to norsk-ctl init for that), reachable at https://<host> — and with no products registered. That is step 2.

Every question is also a flag, and a run that names them asks nothing. This is the form for a cloud box, a rebuild you have done before, and anything scripted — cloud-init, CI, Ansible — where there is nobody to answer prompts:

Terminal window
read -rs -p 'Admin password: ' NORSK_ADMIN_PASSWORD; echo
export NORSK_ADMIN_PASSWORD
curl -fsSL https://norsk.video/install/ctl \
| bash -s -- --server --license /path/to/license.json --yes

The admin password is an exported environment variable, not a flag — a password on a command line ends up in shell history and in ps. It must be 8+ characters with at least one digit.

Server installs are Linux only — Ubuntu 22.04 / 24.04 / 26.04 LTS, Debian 12, or Oracle Linux 9.

On a cloud box, add --public-host <dns-or-ip> so the address clients actually use goes into the TLS certificate and the advertised instance URLs. Use --public-host auto (or its alias --ip auto) to probe for the public IP.

--print shows the plan without changing anything, and --check runs the server preflight (CPU, RAM, free disk, arch, AVX2 on x64, cgroup v2) against the minimums and exits — handy to vet a box before committing to an install. --help lists every flag, and works in the piped form above:

Terminal window
curl -fsSL https://norsk.video/install/ctl | bash -s -- --help

The interview offers this as option 1. To name it up front instead, pass --local:

Terminal window
curl -fsSL https://norsk.video/install/ctl | bash -s -- --local

Note there’s no sudo — a local install puts the CLI in ~/.local/bin and everything else under ~/.norsk-ctl, and it refuses to run as root. It takes no other flags: it installs the CLI and stops, and configuration is norsk-ctl init’s job, so --license, --public-host, the --cert-* flags and the port flags all belong to a server install. Pass one here and the installer stops and says so rather than dropping it — a license in particular is supplied per product, at norsk-ctl product add --license-file <file>.

Then run norsk-ctl init. Docker Desktop or OrbStack has to be running, since registering a product runs its container. The UI lives at https://localhost, with a self-signed certificate (so expect a browser warning; norsk-ctl init --cert-source mkcert issues a locally trusted one instead, which installs a CA into your system trust store).

If the box already serves something on 443 or 80

Section titled “If the box already serves something on 443 or 80”

The proxy binds 443, plus 80 for an HTTP→HTTPS redirect, and the daemon listens on 8333. The install checks all three before it changes anything and stops with the port and the process holding it, so a busy box costs you a second rather than a half-finished install. Move ours:

Terminal window
curl -fsSL https://norsk.video/install/ctl \
| bash -s -- --license /path/to/license.json \
--proxy-port 8443 --http-redirect-port 8080

--no-http-redirect drops the redirect listener instead of moving it. The UI is then at https://<host>:8443.

If another reverse proxy fronts this box — publishing 443 and forwarding to us — also name the port clients arrive on, because every advertised URL uses it rather than the port we bind:

Terminal window
… --proxy-port 8443 --external-port 443 --public-host studio.example.com

Without --external-port the sign-in redirect and each instance’s links would name :8443, which the fronting proxy doesn’t publish. See Behind another reverse proxy.

Registering a product is one command against the running daemon. It pulls the image, reads the product’s manifest, and imports the product’s default template:

Terminal window
norsk-ctl product add --image norskvideo/norsk-studio-product:2026-07-21-a3d4d173 --license-file /etc/norsk-ctl/licenses/license.json

The license path must be readable by the daemon — the installer’s --license stages it under /etc/norsk-ctl/licenses/, keeping your filename, and prints the exact path (a local install uses the path to your own license file).

That example registers Norsk Studio. Other products are the same command with their own image; each product’s own documentation names its image and any options it takes.

If a product is the whole reason you are here, that product’s bootstrap does step 1 and step 2 in order, with one set of questions:

Terminal window
curl -fsSL https://norsk.video/install/studio | bash

That is the same norsk-ctl install as above, followed by registering Studio — convenience, not a different platform. It additionally accepts --admin-password as a flag (as well as NORSK_ADMIN_PASSWORD), and --launch-examples to start the sample-workflow instance as part of the install.

Sign in at https://<host> as admin and launch an instance from a registered product’s template on the dashboard — or from the CLI:

Terminal window
norsk-ctl template list
norsk-ctl instance launch-template my-studio --template studio-examples --param INSTANCE_NAME=my-studio

New to the model? The Learn the model tutorials walk through product → product template → instance step by step.