Skip to content

Zero to Hero (Interactive Setup)

The interactive wizard is the shortest path from a fresh install to a working norsk-ctl configuration. Run norsk-ctl init with no flags in a terminal and a form-style UI walks you through every field — license path, network mode, TLS, proxy user, image tag overrides. No manual YAML.

Run the command with no arguments:

$ norsk-ctl init

You’ll see a bordered form:

╭───────────────────────────────────────────────────────────────────────╮
│ norsk-ctl setup │
│ Tab to move between fields · Enter to submit field · Esc to cancel │
│ │
│ ▶ License file │
│ _ │
│ Press Enter to continue · Esc to cancel │
│ │
│ Network mode │
│ docker — bridge network + reverse proxy (typical) │
│ │
│ TLS │
│ insecure — HTTP only (local/eval) │
│ │
│ Working directory (optional) │
│ Leave blank for built-in default (~/.norsk-ctl/workspaces) │
│ │
│ Add proxy user (optional) │
│ │
│ Studio image tag (optional) │
│ Media image tag (optional) │
│ │
│ [ Submit ] [ Cancel ] │
╰───────────────────────────────────────────────────────────────────────╯

The ▶ marker shows the active field. Tab / Shift-Tab cycle between fields.

Start typing and the wizard fuzzy-matches children of the current directory, ghosting the likely completion inline. Fish-style — there’s no “TAB to accept”, just keep typing or press Enter when the suggestion looks right:

▶ License file
/Users/alice/licensing/in_[ternal_dev_license.json]

The ghosted portion (in brackets above) shows as dimmed text in your terminal. Press Enter and the wizard validates the path exists and is a file (not a directory), then advances focus to Network mode. ~/ is expanded before validation, so ~/licensing/dev.json works.

On Linux, pick one of docker (bridge network + reverse proxy, the typical choice), hybrid (studio proxied, media on host network), or host (everything on host network).

On macOS, docker is the only option — host and hybrid rely on Linux host networking which Docker Desktop doesn’t provide. The wizard shows this explicitly:

▶ Network mode
● docker — bridge network + reverse proxy (typical)
✗ hybrid — studio proxied, media on host network (unavailable on macOS)
✗ host — everything on host network (unavailable on macOS)
macOS: host/hybrid need Linux host networking — not supported on Docker Desktop

The unavailable options are struck through in yellow; the active choice is highlighted green.

Four options, arrow keys to change:

▶ TLS
insecure — HTTP only (local/eval)
mkcert — local development only (auto-install, may prompt for sudo) — https://github.com/FiloSottile/mkcert
user-supplied — bring your own cert + key
certbot — Let's Encrypt (needs public DNS)

mkcert is for local development only — it installs a root CA on your own machine so dev browsers trust certs it issues. Don’t use it for anything another machine needs to trust; for that, use certbot or user-supplied with a real CA-issued cert.

Picking mkcert triggers an automated pipeline after you submit — see the next section.

user-supplied reveals two extra fields (TLS certificate, TLS private key) that must point at existing PEM files.

If you pick mkcert, you don’t enter any cert paths. After you submit, the wizard exits Ink and runs the mkcert pipeline in the plain terminal:

Setting up local-trust TLS with mkcert
https://github.com/FiloSottile/mkcert
mkcert not found — downloading…
100%
downloaded: /Users/alice/.norsk-ctl/bin/mkcert
About to install the mkcert root CA into your system trust store.
This requires sudo and will prompt for your password.
Press Enter to continue (Ctrl-C to abort)…
Password: ********
running mkcert -install…
The local CA is already installed in the system trust store! 👍
generating cert for: localhost, 127.0.0.1, ::1
wrote /Users/alice/.norsk-ctl/certs/cert.pem

On repeat runs the wizard notices the CA is already in your trust store and skips the sudo prompt entirely:

Setting up local-trust TLS with mkcert
using mkcert at /Users/alice/.norsk-ctl/bin/mkcert
local CA already installed — skipping sudo prompt
generating cert for: localhost, 127.0.0.1, ::1
wrote /Users/alice/.norsk-ctl/certs/cert.pem

The generated cert + key are written to ~/.norsk-ctl/certs/, and the wizard patches certPath / keyPath / certSource: mkcert onto the config before writing config.yaml.

Type a username and press Enter — the wizard reveals a password field:

▶ Add proxy user (optional)
admin
Proxy password
********
≥8 chars, includes a digit

Skip it by leaving the username blank and tabbing onward. Existing users (from a previous run) are shown as a hint and not re-prompted — the wizard only ever adds users from here.

Existing config — overwrite confirmation

Section titled “Existing config — overwrite confirmation”

If a config.yaml already exists, the wizard shows a yellow warning pre-screen before the form appears:

╭───────────────────────────────────────────────────────────────────────╮
│ norsk-ctl setup │
│ │
│ ⚠ Existing config detected — continuing will overwrite it and wipe │
│ the instance database. │
│ │
│ Current config │
│ Network mode: docker │
│ License mode: byol │
│ License file: /Users/alice/licensing/internal_dev_license.json │
│ Cert source: mkcert │
│ Proxy users: admin │
│ │
│ Proceed? y/N │
╰───────────────────────────────────────────────────────────────────────╯

Type y to continue into the form (seeded with the current values as defaults) or n to exit. Either way the existing database is preserved until you actually submit.

After Submit, the wizard prints the equivalent flag-driven command:

Config written to /Users/alice/.norsk-ctl/config.yaml
Proxy user(s) created: admin
Equivalent command: norsk-ctl init --network-mode docker --license-file /Users/alice/licensing/internal_dev_license.json --cert-source mkcert --proxy-user admin --proxy-password '<redacted>'

Copy that line if you’re setting up another machine — it’s script-safe (password is redacted as a literal placeholder, substitute your own).

The daemon auto-starts on the next norsk-ctl command that needs it, so you can go straight to launching:

$ norsk-ctl instance launch my-studio --hardware none

Or visit the web UI at https://localhost:9443/ (mkcert) or http://localhost:9080/ (insecure) — see Quickstart Demo for the full walkthrough.

KeyAction
Tab / Shift-TabMove between fields
EnterSubmit the current field (validates + advances)
↑ / ↓Change selection in a Select field
EscCancel the wizard (no config written)
Ctrl-CAbort at any point