Launch modes
The launch mode decides what actually runs when your container starts, which ports get published, and whether your on-start script is applied at all. It is the single most consequential field on a template.
The four modes
args | ssh | jupyter | vm | |
|---|---|---|---|---|
| What starts | the image's own entrypoint | the base image entrypoint: sshd on port 22 | sshd plus JupyterLab over HTTPS | a full KVM virtual machine |
| Base-derived image | not required | required | required | not required |
| Implicit ports | none | 22 prepended, labeled ssh | 22 (ssh) and 8080 (jupyter) prepended | 22 prepended, labeled ssh |
| Your declared ports | published as-is | appended after 22, labeled app | appended after 22 and 8080, labeled app | appended after 22, labeled app |
args_str | split into the container command | ignored | ignored | ignored |
onstart | not applied | runs once at first start | runs once at first start | sent with the launch |
| Offer requirement | none | none | none | a VM-capable offer |
| Connect with | your own published ports | SSH | the Open JupyterLab button, or SSH | SSH |
args
The default. Superheat runs your image exactly as its author intended: the image's native entrypoint, with args_str split into the command using shell word rules. --model llama-3 --port 8000 becomes four arguments.
Nothing is injected into the startup path, which is why onstart has no effect here — there is no Superheat entrypoint to run it. If you need setup work in args mode, bake it into the image or make it the first thing your command does.
Use args for inference servers, training jobs, and any upstream image you did not build.
ssh
Boots the Superheat base entrypoint, which installs your public key into /root/.ssh/authorized_keys, starts sshd on container port 22, runs your on-start script once, and then hands off to the image's CMD (or idles so the container stays up).
Container port 22 is prepended to the port list automatically; you do not declare it. The host-side port is assigned from the machine's published range and is never 22 — the instance page renders the full connect string for you.
Use ssh when you want a machine to work on rather than a service to call.
jupyter
Everything ssh does, plus JupyterLab. Container ports 22 and 8080 are both prepended. Jupyter binds to 0.0.0.0:8080 over HTTPS with a self-signed certificate, rooted at your Jupyter working dir (/workspace by default). Turning the JupyterLab switch off serves the classic notebook instead.
The access token is minted by the platform, passed down to the container, and never returned in any API response. The console assembles the Open JupyterLab link with the token already in it, which is the only way to get it.
Jupyter is served over HTTPS with a self-signed certificate so the token and your notebook traffic are encrypted on the direct path. The warning is expected.
vm
A full KVM virtual machine rather than a container. VM templates only launch onto an offer whose host is VM-capable. On the deploy page a VM template picked against a non-VM-capable offer is unselectable, with "This machine is not VM-capable." as the reason, and the Deploy button stays disabled; the API enforces the same rule and returns 422 OFFER_NOT_VM_CAPABLE. The launch is compiled with SSH access, so you connect the same way you would in ssh mode.
No base-derived image is required, because the VM is not running the container entrypoint.
Why ssh and jupyter need a base-derived image
A plain upstream image like pytorch/pytorch ships neither sshd nor JupyterLab, so there is nothing for those modes to start. Superheat detects a usable image by the com.superheat.base label, which is set by the published base image and inherited by anything built FROM it.
If you point an ssh or jupyter template at an image that does not carry the label, the launch has nothing to boot. Either build your image on the base — see Base image — or switch the template to args.
Port precedence
After the implicit ports are prepended, the list is de-duplicated by container port and protocol, and the higher-priority entry wins:
ssh / jupyter > open_button > app
That ordering lets you declare a port in the ports list and point the Open button at it: the entry comes back labeled open_button rather than app. It also means declaring 22 or 8080 yourself in ssh or jupyter mode changes nothing — the implicit entry keeps its role.
See Ports for labels and the Open button.
Changing mode later
The launch mode is part of the launch recipe, so editing it re-mints the template's hash_id and any pinned share link stops resolving. Running instances are unaffected — they keep the recipe they launched with.