Ports
Declare a port on a template and Superheat publishes it when the instance launches, mapping the container port to a host port on the machine you rented. Anything your workload listens on that you want to reach from outside — an inference server, a web UI, a metrics endpoint — needs a row here.
Declaring a port
Each row in the Ports section has four parts.
| Part | Accepts | Meaning |
|---|---|---|
| Container port | 1 to 65535 | The port your process listens on inside the container. |
| Protocol | tcp, udp, http, https | What the port serves. http and https are published over TCP; the distinction records intent and drives how the console presents the port. |
| Label | up to 64 characters | A human name, shown on the template detail. Some values are reserved — see below. |
| Public | switch, on by default | Recorded on the port entry. |
You declare the container port only. The host port is assigned at launch from the machine's published range, and you will not know it in advance. Inside the container, each published TCP port is available as SUPERHEAT_TCP_PORT_<container_port>:
echo "$SUPERHEAT_TCP_PORT_7860"
That environment variable is how you read the host port from inside your workload. The instance page's Connect tab renders the SSH command and, where the template has one, the Open or Open JupyterLab link. See Ports and networking.
Labels
Labels are trimmed and compared without case, and six of them map onto the four reserved roles.
| Label | Effect |
|---|---|
open, open_button, open-button | Makes this the Open button target. The port is published with the open_button role and its number is passed to the container as OPEN_BUTTON_PORT. |
ssh | Published with the ssh role. |
jupyter | Published with the jupyter role. |
app | Published with the app role — the default. |
| anything else | Kept as the display label; the port is published with the app role. |
So a port labeled Jupyter, jupyter or JUPYTER all mean the same thing, while Gradio UI is a plain app port with a friendly name.
Ports you do not declare
Launch modes prepend the ports they need. In ssh mode, container port 22 is added for you. In jupyter mode, 22 and 8080 are both added. Declaring them yourself is harmless but redundant: the list is de-duplicated by container port and protocol, and the implicit entry wins over a plain app entry.
The precedence, highest first, is ssh and jupyter, then open_button, then app. That is what lets a template both declare a port in the list and point the Open button at it — the surviving entry carries the open_button role.
In args mode nothing is prepended. If you want SSH access to an args template, you are responsible for running an SSH server in the image and declaring the port yourself, or you should switch to ssh mode with a base-derived image.
The Open button port
The console shows an Open button on an instance when the template named a target port. Set it by labeling exactly one port open:
{
"ports": [
{ "container_port": 7860, "protocol": "http", "label": "open", "public": true },
{ "container_port": 9090, "protocol": "http", "label": "metrics", "public": true }
]
}
Label more than one port open and the last one in the list wins, which is rarely what you meant. Declare one.
In jupyter mode you do not need an Open button port at all — the console renders Open JupyterLab from the Jupyter role, with the access token already in the URL. See JupyterLab.
Ports are part of the recipe
The ports list is a launch field, so editing it re-mints the template's hash_id and invalidates pinned share links. Running instances keep the port map they launched with; a new port only appears on instances deployed after the edit.