Zero to Hero (Hybrid Mode, CLI)
First installation
Section titled “First installation”Initialise norsk-ctl
Section titled “Initialise norsk-ctl”Run norsk-ctl init to create the configuration file. Hybrid mode puts studio on the Docker bridge (proxied) and media on the host network for low-latency ingest.
$ norsk-ctl init --network-mode hybrid --working-directory /tmp/workspace --proxy-user admin --proxy-password testpass1Proxy 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: 305096cf24c1a1f7c44c45d9b8578c78aadc1136e65bc172b2325818e0065ebaaddedAt: 2026-08-04T19:21:16.683Zrunning: 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:21:16.687Z 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:21:16.700Z 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:21:16.701Z 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:21:16.703Z 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. --network-mode hybrid keeps media on the host network for low-latency ingest while studio stays proxied on the Docker bridge.
$ norsk-ctl instance launch-template my-studio --template studio-examples --param INSTANCE_NAME=my-studio --network-mode hybridkind: 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:21:23.838ZproductComponents: []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: hybridshmSize: 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-hybrid-cli image: nginx tag: 1.29.7-alpine status: running uptime: 15 seconds ago role: proxy - name: norsk-proxy-guide-hybrid-cli-oauth2 image: quay.io/oauth2-proxy/oauth2-proxy tag: v7.15.1-alpine status: running uptime: 15 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:21:23.838Z 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: hybrid 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:21:23.838ZproductComponents: []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: hybridshmSize: 2gbSign in to the proxy
Section titled “Sign in to the proxy”In hybrid mode the studio is reached through the proxy, just like Docker mode — sign in first.

Sign in with the proxy user you configured during init.
Open Norsk Studio
Section titled “Open Norsk Studio”Once signed in, open the Studio UI 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 435774)