Server install walkthrough (Ubuntu)
A real, start-to-finish run of the one-shot --server installer on a fresh box — every command and its actual output, annotated. By the end you’ll have the norsk-ctl daemon running under systemd behind a TLS proxy, ready to sign into.
Throughout: command blocks are highlighted and have a copy button — those are what you type. Output blocks are plain and have no copy button — that’s what you should see back.
Before you begin
Section titled “Before you begin”You’ll need:
- A fresh Ubuntu 22.04 / 24.04 / 26.04 LTS or Debian 12 box with
sudoand SSH access. Aim for 8 vCPU / 16 GB RAM / 60 GB+ disk. - Your Norsk license file (
license.json) on your laptop — you’ll copy it across in step 1. - A password for the
adminweb user — pick a strong one. You’ll pass it via an environment variable so it never lands in your shell history. - The address clients will use to reach the box — its public IP or DNS name. Below we write
<host>; substitute your box’s address.
The install takes ~3–5 minutes, mostly installing Docker. It does not pull the large Studio/Media images by default — add --pull-images if you want them fetched up front.
1. Copy your license to the box
Section titled “1. Copy your license to the box”From your laptop:
scp license.json ubuntu@<host>:/tmp/license.json2. Run the installer
Section titled “2. Run the installer”SSH into the box, download the installer, set your admin password, and run it in --server mode. The full source of install.sh is inlined in the reference if you want to read it before running — see Reference: the installer. The flags:
--server— full daemon install: Docker (if missing), anorskservice user, a systemd unit, and TLS.--license— the license file you just copied.--public-host— the address clients use; it goes into the self-signed certificate. (Use--ip autoto auto-detect a public IP instead.)
The installer prints its plan and asks you to confirm before touching the box. Type y at the [y/N]: prompt to proceed — pass --yes to skip it in automation.
curl -fsSL https://s3.eu-west-1.amazonaws.com/norsk.video/norsk-ctl/install.sh -o install.shread -rs -p 'Admin password: ' NORSK_ADMIN_PASSWORD; echoexport NORSK_ADMIN_PASSWORDbash install.sh --server --license /tmp/license.json --public-host <host>preflight — server capability check: warn CPU cores 4 vCPU (8 vCPU recommended) warn RAM 4 GB (16 GB recommended) warn free disk 22 GB (100 GB recommended) ok cgroup unified hierarchy ok arch arm64norsk-ctl install plan — mode: server, platform: linux-<arch>
public host <host> cert source self-signed licence /tmp/license.json
server (Ubuntu LTS, Debian, or Oracle Linux; uses sudo per step, not run as root): 1. If 'docker compose' is missing, install Docker Engine + the Compose plugin from Docker's official package repository. 2. Create the 'norsk' service user and FHS dirs under /etc, /var/lib, /var/log. 3. Install the CLI to /opt/norsk-ctl/bin with a /usr/local/bin/norsk-ctl symlink. 4. Apply sysctl tuning and write a systemd unit (norsk-ctl.service). 5. Configure the daemon (via 'norsk-ctl init', TLS: self-signed by default), then enable + start the norsk-ctl systemd unit so it comes up on boot.
Proceed — install Docker (if needed), a systemd service, and start norsk-ctl? (will use sudo for each system step)[y/N]:
==> installing Docker Engine + Compose plugin==> added <user> to the docker and norsk groups (open a new shell, or run 'newgrp norsk' — one call activates both)==> installed norsk-ctl <version>==> license staged at /etc/norsk-ctl/licenses/license.json — register products with 'norsk-ctl product add --license-file /etc/norsk-ctl/licenses/license.json'Proxy user "admin" createdConfig written to /etc/norsk-ctl/config.yaml (TLS enabled)Public URL (from --public-host): https://<host>════════════════════════════════════════════════════════════════==> install complete UI: https://<host> (sign in as admin) Service: systemctl status norsk-ctl Logs: journalctl -u norsk-ctl -f Shell: source /etc/profile.d/norsk-ctl.sh (or open a new shell) Files: Config /etc/norsk-ctl config.yaml, licenses/, certs/ State /var/lib/norsk-ctl database, product registry, templates, instances, proxy Logs /var/log/norsk-ctl per-instance and proxy logs Binary /opt/norsk-ctl/bin versioned; /usr/local/bin/norsk-ctl symlinks to it Back up /etc/norsk-ctl and /var/lib/norsk-ctl to capture config + state.════════════════════════════════════════════════════════════════read -rs reads the password into the variable without echoing it to the terminal and without it ever appearing in your shell history. In a longer-running deployment you’d typically pull this from a secrets manager (Vault, AWS Secrets Manager, etc.) into the same env var instead — and the proxy auth layer itself can also be replaced by an SSO integration as part of a production setup.
You don’t need to run the installer with sudo yourself — install.sh runs as you and escalates via sudo only for the system-mutation steps (apt-get, writes under /etc and /opt, systemctl). You’ll be prompted once for your sudo password after you confirm the plan; sudo caches the credential for the rest of the run.
That last ==> UI: line is your finish line. Reading the output top to bottom: the installer printed its plan and you confirmed with y; Docker was installed and enabled, the norsk service user and its directories were created, norsk-ctl init wrote /etc/norsk-ctl/config.yaml and minted a self-signed cert for <host>, and the norsk-ctl systemd service was enabled and started.
3. What got installed
Section titled “3. What got installed”Before checking the daemon, here’s where install.sh put things. Knowing the layout makes troubleshooting later much easier.
Config: the rendered config.yaml and the licence install.sh copied in. For self-signed TLS, the cert and key sit alongside them in the certs/ subdirectory shown above (owned by the norsk service user).
ls -l /etc/norsk-ctl/total 12drwxr-xr-x 2 norsk norsk 4096 <timestamp> certs-rw-r--r-- 1 norsk norsk 187 <timestamp> config.yamldrwxr-x--- 2 norsk norsk 4096 <timestamp> licensesBinary: the versioned norsk-ctl binary lives here; /usr/local/bin/norsk-ctl is a symlink to it so upgrades are just a re-symlink.
ls -l /opt/norsk-ctl/bin/total 108356-rwxr-xr-x 1 norsk norsk 110954816 <timestamp> norsk-ctl-<version>Systemd unit: managed by systemctl {start,stop,status} norsk-ctl.
ls -l /etc/systemd/system/norsk-ctl.service-rw-r--r-- 1 root root 568 <timestamp> /etc/systemd/system/norsk-ctl.service4. Verify it’s running
Section titled “4. Verify it’s running”norsk-ctl --version<version>systemctl is-active docker norsk-ctl.serviceactiveactiveTwo active lines mean Docker and the daemon are both up.
If you plan to drive the CLI from this same shell (e.g. norsk-ctl user set <name>), source the env file once so it picks up the production paths the installer just wrote:
source /etc/profile.d/norsk-ctl.shA fresh login (or ssh session opened after the install) does this for you. Without it the CLI looks under ~/.norsk-ctl/ for the proxy secret and the daemon redirects with Redirected to proxy — stale or missing proxy secret.
5. Sign in
Section titled “5. Sign in”Open https://<host> and sign in as admin with the password you set. Your browser shows a one-time “not trusted” warning — that’s the self-signed certificate. It’s real TLS, so it’s safe to continue.
6. Register a product
Section titled “6. Register a product”norsk-ctl is the control plane — a fresh install has no product registered, so there’s nothing to launch yet. Register the products your license entitles; the daemon reads the license, pulls each product’s image, reads its manifest, and imports the default (examples) product template:
norsk-ctl product add --license-file /etc/norsk-ctl/licenses/license.jsonThe image comes from the license (add --product <name> to register just one, or --tag <tag> to pin a version). The license path must be readable by the norsk service user — install.sh --license stages your file under /etc/norsk-ctl/licenses/, keeping its filename (here license.json, the name it was copied across as in step 1). See Products & Templates for the full product → template → instance model.
Back in the dashboard, launch a Studio instance from the registered product template — or from the CLI with norsk-ctl template list then norsk-ctl instance launch-template.
Next steps
Section titled “Next steps”- Ports & host detection — what to open in the firewall, and how to change the proxy port.
- Pre-pull the proxy images with
norsk-ctl proxy pull(or pass--pull-imagesat install); a product’s images pull on first launch, or ahead of time withnorsk-ctl product pull <product>once it’s registered. - Stuck?
journalctl -u norsk-ctl -ftails the daemon logs; the Troubleshooting page has the common gotchas.