Zero to Hero (CLI)
First installation
Section titled “First installation”Initialise norsk-ctl
Section titled “Initialise norsk-ctl”Run norsk-ctl init to create the configuration file with your default working directory. This only needs to be done once. Licenses are supplied later, when a product is registered.
$ norsk-ctl init --working-directory /tmp/workspaceProxy user "admin" createdConfig written to ~/.norsk-ctl/config.yamlRegister the Studio product
Section titled “Register the Studio product”Register Norsk Studio as a product. This fetches the product’s manifest and its default product template — a ready-to-launch description of a Studio instance.
$ norsk-ctl product add --image norskvideo/norsk-studio-product:2026-07-21-a3d4d173 --license-file ~/norsk-license.jsonname: norsk-studiospec: kind: container image: norskvideo/norsk-studio-product:2026-07-21-a3d4d173port: 14321containerId: 34f98d376438ccb0858d08b68cd813d2547d950fa75bb58abcf171e463d12888addedAt: 2026-08-04T19:20:51.199Zrunning: truehealth: unknownmanifest: manifestSchemaVersion: 1 name: norsk-studio version: 0.0.1 minRunnerVersion: 0.1.0 api: basePath: /api proxyPaths: - /api/* - /configure - /configure/* openapiFragmentPath: /api/openapi.yaml mcpPath: /mcp healthCheckPath: /healthz productMcpPath: /mcp ui: configScreenUrl: /configure sidebarEntries: [] dashboardWidgets: [] productTemplateActions: - label: Add examples product template configScreenUrl: /configure?template=examples - label: Add dev product template configScreenUrl: /configure?template=dev cli: subcommandTree: - name: plugin description: Scaffold and build Norsk Studio plugins flags: [] subcommands: - name: create description: "Scaffold a new plugin into the working directory's components/" flags: - name: name description: Plugin package name required: true - name: workingDirectory description: Working directory to scaffold into required: true - name: studioTag description: Studio image tag to scaffold against request: method: POST path: /api/plugins/create - name: list description: List plugins discovered in the working directory flags: - name: workingDirectory description: Working directory to inspect required: true request: method: GET path: /api/plugins - name: install description: Install an npm package as a plugin into the working directory flags: - name: pkg description: npm package to install required: true - name: workingDirectory description: Working directory to install into required: true - name: studioTag description: Studio image tag to install against request: method: POST path: /api/plugins/install - name: build description: "Bake the working directory's plugins into a studio image" flags: - name: tag description: Tag for the baked image required: true - name: workingDirectory description: Working directory whose plugins to bake required: true - name: fromImage description: Base studio image to bake onto - name: fromTag description: Base studio image tag - name: push description: Push the baked image to its registry type: boolean request: method: POST path: /api/plugins/build targets: - docker-compose components: [] runtime: sharedWorkingDirectory: false defaultProductTemplates: - name: studio-examples url: /api/product-templates/examples - name: studio-dev url: /api/product-templates/dev export: include: - studio-save-files/** - dashboards/** - components/** - assets/** - "*.yml" - "*.yaml" exclude: - "**/node_modules/**" - recordings/** - logs/** - "**/*.mp4" - "**/*.ts3"license: mode: byol file: ~/.norsk-ctl/licenses/norsk-license.jsonwarnings: - license is marked NON-PRODUCTION — not valid for production deploymentsThe registered product template is now available to launch from.
$ norsk-ctl template listproductTemplates: - name: studio-examples manifest: productTemplateSchemaVersion: 1 productName: norsk-studio productVersion: 0.0.1 target: docker-compose generatedAt: 2026-08-04T19:20:51.202Z ui: runtimeScreenUrl: / runtimeScreenLabel: Open Studio debug: studio: false proxy: expose: - / - /static/* - /api/* - /live/api/* - /dashboard/* - /ws - /ws/* - /live/* - /components/* advanced: networkMode: {} containerUser: {} publicHost: {} hostPorts: {} allocatedPorts: - param: GLOBAL_MOQ_PREVIEW_WEBTRANSPORTPORT protocol: udp preferred: 30000 label: MoQ preview (WebTransport) parameters: - name: INSTANCE_NAME purpose: Compose project label for this Studio instance type: string required: true - name: GLOBAL_MOQ_PREVIEW_WEBTRANSPORTPORT purpose: "MoQ preview (WebTransport) UDP port. Omit to keep it closed; 'auto' allocates a free high port; or give a port number." type: string createdAt: 2026-08-04T19:20:51.214Z source: kind: product-default productName: norsk-studio url: /api/product-templates/examples - name: studio-dev manifest: productTemplateSchemaVersion: 1 productName: norsk-studio productVersion: 0.0.1 target: docker-compose generatedAt: 2026-08-04T19:20:51.215Z ui: runtimeScreenUrl: / runtimeScreenLabel: Open Studio debug: studio: false proxy: expose: - / - /static/* - /api/* - /live/api/* - /dashboard/* - /ws - /ws/* - /live/* - /components/* requiresWorkingDirectory: true advanced: networkMode: {} containerUser: {} publicHost: {} hostPorts: {} allocatedPorts: - param: GLOBAL_MOQ_PREVIEW_WEBTRANSPORTPORT protocol: udp preferred: 30000 label: MoQ preview (WebTransport) parameters: - name: INSTANCE_NAME purpose: Compose project label for this Studio instance type: string required: true - name: GLOBAL_MOQ_PREVIEW_WEBTRANSPORTPORT purpose: "MoQ preview (WebTransport) UDP port. Omit to keep it closed; 'auto' allocates a free high port; or give a port number." type: string createdAt: 2026-08-04T19:20:51.218Z source: kind: product-default productName: norsk-studio url: /api/product-templates/devLaunch an instance from the product template
Section titled “Launch an instance from the product template”Launch a Studio instance from the product’s template.
$ norsk-ctl instance launch-template my-studio --template studio-examples --param INSTANCE_NAME=my-studiokind: productid: my-studioproductTemplateName: studio-examplesproductName: norsk-studioproductVersion: 0.0.1params: INSTANCE_NAME: my-studio NORSK_ALLOCATED_PORTS: "{}"workingDirectory: /tmp/workspace/norsk-studio/my-studiolaunchedAt: 2026-08-04T19:20:58.433ZproductComponents: []runtimeScreen: url: / href: /instance/my-studio/ label: Open Studio ready: falsedebug: studio: falsemcp: uri: http://my-studio-studio-1:8000/mcp ready: falselinks: - key: visualiser label: Open Visualiser href: /instance/my-studio/visualiser/ ready: falsestatus: stoppedservices: []serviceStatus: {}networkMode: dockershmSize: 2gbCheck instance status
Section titled “Check instance status”$ norsk-ctl instance listinfrastructure: - name: norsk-product-norsk-studio image: norskvideo/norsk-studio-product tag: 2026-07-21-a3d4d173 status: running uptime: 14 seconds ago role: product - name: norsk-proxy-guide-cli image: nginx tag: 1.29.7-alpine status: running uptime: 14 seconds ago role: proxy - name: norsk-proxy-guide-cli-oauth2 image: quay.io/oauth2-proxy/oauth2-proxy tag: v7.15.1-alpine status: running uptime: 14 seconds ago role: proxy-oauth2instances: - kind: product id: my-studio productTemplateName: studio-examples productName: norsk-studio productVersion: 0.0.1 params: INSTANCE_NAME: my-studio NORSK_ALLOCATED_PORTS: "{}" workingDirectory: /tmp/workspace/norsk-studio/my-studio launchedAt: 2026-08-04T19:20:58.433Z productComponents: [] runtimeScreen: url: / href: /instance/my-studio/ label: Open Studio ready: true debug: studio: false mcp: uri: http://my-studio-studio-1:8000/mcp ready: false links: - key: visualiser label: Open Visualiser href: /instance/my-studio/visualiser/ ready: true status: healthy services: - media - studio serviceStatus: studio: healthy media: healthy networkMode: docker shmSize: 2gb$ norsk-ctl instance describe my-studiokind: productid: my-studioproductTemplateName: studio-examplesproductName: norsk-studioproductVersion: 0.0.1params: INSTANCE_NAME: my-studio NORSK_ALLOCATED_PORTS: "{}"workingDirectory: /tmp/workspace/norsk-studio/my-studiolaunchedAt: 2026-08-04T19:20:58.433ZproductComponents: []runtimeScreen: url: / href: /instance/my-studio/ label: Open Studio ready: truedebug: studio: falsemcp: uri: http://my-studio-studio-1:8000/mcp ready: falselinks: - key: visualiser label: Open Visualiser href: /instance/my-studio/visualiser/ ready: truestatus: healthyservices: - media - studioserviceStatus: studio: healthy media: healthynetworkMode: dockershmSize: 2gbSign in to the proxy
Section titled “Sign in to the proxy”Norsk Studio is served through the authenticating proxy, so the first request lands on a sign-in form.

Sign in with the proxy user you configured during init.
Open Norsk Studio
Section titled “Open Norsk Studio”Once signed in, the Studio UI is reachable through the proxy.

Clean up
Section titled “Clean up”Delete the instance to stop its containers and free resources.
$ norsk-ctl instance delete my-studioInstance my-studio terminatedThe proxy is needed whenever instances are running — with no instances left, it can be stopped to free the port.
$ norsk-ctl proxy stopThe daemon can be stopped and restarted at any time — running instances and the proxy are unaffected.
$ norsk-ctl shutdown --daemon-onlyDaemon stopped (pid 430222)