Skip to content

Cloud deployment

Two paths to running norsk-ctl in the cloud: a marketplace image with everything pre-installed, or a manual install on any VM that can run Docker.

A pre-built Ubuntu image that ships norsk-ctl + Docker + systemd integration. Launch from the GCP marketplace and the first boot auto-configures based on instance metadata.

Set these on the VM at creation time (GCP console → ManagementMetadata, or via gcloud compute instances add-metadata):

KeyRequiredDescription
norsk-studio-admin-passwordyesPassword for the initial proxy user (norsk-studio-admin). Setting this triggers first-boot init
deploy_domain_nameoptionalDomain name pointed at the VM. Enables Let’s Encrypt via certbot
deploy_certbot_emailoptionalContact email for Let’s Encrypt. Required if deploy_domain_name is set

Without a domain, the first boot generates a self-signed certificate covering the VM’s public IP. HTTPS works; browsers show a one-time warning.

The startup script (deployment/google/files/gcp-startup.sh) on the image:

  1. Reads the metadata keys above.
  2. If config.yaml doesn’t exist yet, runs norsk-ctl init --network-mode docker with the metadata values, plus --cert-source certbot (with domain) or --cert-source self-signed (IP-only).
  3. On every boot, refreshes publicHost in config from the current instance metadata to catch IP changes.
  4. Execs norsk-ctl serve as a systemd unit.

Within a couple of minutes of VM boot you should be able to reach the web UI at https://<vm-ip-or-domain>/ and sign in as norsk-studio-admin.

product add --marketplace-provider aws is accepted for per-product marketplace licensing, but a published AWS image is not shipping yet.

The standard install.sh --server flow works on any Ubuntu 22.04 / 24.04 / 26.04 LTS, Debian 12, or Oracle Linux 9 VM with outbound HTTPS:

Terminal window
# On the VM
scp /path/to/license.json ubuntu@<public-ip>:/tmp/license.json
ssh ubuntu@<public-ip>
curl -fsSL https://s3.eu-west-1.amazonaws.com/norsk.video/norsk-ctl/install.sh -o install.sh
read -rs -p 'Admin password: ' NORSK_ADMIN_PASSWORD; echo
export NORSK_ADMIN_PASSWORD
sudo --preserve-env=NORSK_ADMIN_PASSWORD bash install.sh \
--server --license /tmp/license.json --ip auto

This installs Docker (if missing), the norsk-ctl binary, a systemd service, and configures TLS with a self-signed cert covering the auto-detected public IP. For a real DNS name + Let’s Encrypt:

Terminal window
sudo --preserve-env=NORSK_ADMIN_PASSWORD bash install.sh \
--server --license /tmp/license.json \
--cert-source certbot --domain norsk.example.com --cert-email ops@example.com

Full reference: Server install — overview.

The same recommendations from Security, with the cloud-VM specifics called out:

  • Firewall :8333. The daemon API is unauthenticated by design — meant to be reachable from localhost only. Block inbound :8333 at your cloud provider’s firewall.
  • Expose only the proxy port. :443 (and :80 for the HTTP→HTTPS redirect / certbot HTTP-01 validation). Add ingest ports your pipelines listen on (typically 5001+ for SRT).
  • Use real TLS certs. Let’s Encrypt via --cert-source certbot if you have a domain, or bring your own with --cert-source user. Self-signed is fine for evaluation but every browser gets a warning.
  • Rotate the proxy admin password. Set a strong one at init via NORSK_ADMIN_PASSWORD; change later with norsk-ctl user set <admin>.
  • Restrict SSH with cloud-provider SSH-over-IAP or an equivalent.

The norsk-ctl CLI is a local admin tool — it always talks to a daemon on the same machine. To manage a cloud instance, either:

  • Use the web UI behind the proxy (the normal remote path, authenticated by basic auth or OAuth2).
  • Use the MCP servernorsk-ctl mcp on the VM exposes the daemon over MCP. The stdio bridge is local; if you want remote MCP, the HTTP /mcp endpoint is reachable via the proxy (but the loopback-bypass means external /mcp requests are blocked — only the local stdio bridge works today).
  • SSH to the VM and run norsk-ctl there.